unityflow 0.3.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- unityflow/__init__.py +167 -0
- unityflow/asset_resolver.py +636 -0
- unityflow/asset_tracker.py +1687 -0
- unityflow/cli.py +2317 -0
- unityflow/data/__init__.py +1 -0
- unityflow/data/class_ids.json +336 -0
- unityflow/diff.py +234 -0
- unityflow/fast_parser.py +676 -0
- unityflow/formats.py +1558 -0
- unityflow/git_utils.py +307 -0
- unityflow/hierarchy.py +1672 -0
- unityflow/merge.py +226 -0
- unityflow/meta_generator.py +1291 -0
- unityflow/normalizer.py +529 -0
- unityflow/parser.py +698 -0
- unityflow/query.py +406 -0
- unityflow/script_parser.py +717 -0
- unityflow/sprite.py +378 -0
- unityflow/validator.py +783 -0
- unityflow-0.3.4.dist-info/METADATA +293 -0
- unityflow-0.3.4.dist-info/RECORD +25 -0
- unityflow-0.3.4.dist-info/WHEEL +5 -0
- unityflow-0.3.4.dist-info/entry_points.txt +2 -0
- unityflow-0.3.4.dist-info/licenses/LICENSE +21 -0
- unityflow-0.3.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Package data directory for unityflow
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
{
|
|
2
|
+
"0": "Object",
|
|
3
|
+
"1": "GameObject",
|
|
4
|
+
"2": "Component",
|
|
5
|
+
"3": "LevelGameManager",
|
|
6
|
+
"4": "Transform",
|
|
7
|
+
"5": "TimeManager",
|
|
8
|
+
"6": "GlobalGameManager",
|
|
9
|
+
"8": "Behaviour",
|
|
10
|
+
"9": "GameManager",
|
|
11
|
+
"11": "AudioManager",
|
|
12
|
+
"13": "InputManager",
|
|
13
|
+
"18": "EditorExtension",
|
|
14
|
+
"19": "Physics2DSettings",
|
|
15
|
+
"20": "Camera",
|
|
16
|
+
"21": "Material",
|
|
17
|
+
"23": "MeshRenderer",
|
|
18
|
+
"25": "Renderer",
|
|
19
|
+
"27": "Texture",
|
|
20
|
+
"28": "Texture2D",
|
|
21
|
+
"29": "OcclusionCullingSettings",
|
|
22
|
+
"30": "GraphicsSettings",
|
|
23
|
+
"33": "MeshFilter",
|
|
24
|
+
"41": "OcclusionPortal",
|
|
25
|
+
"43": "Mesh",
|
|
26
|
+
"45": "Skybox",
|
|
27
|
+
"47": "QualitySettings",
|
|
28
|
+
"48": "Shader",
|
|
29
|
+
"49": "TextAsset",
|
|
30
|
+
"50": "Rigidbody2D",
|
|
31
|
+
"53": "Collider2D",
|
|
32
|
+
"54": "Rigidbody",
|
|
33
|
+
"55": "PhysicsManager",
|
|
34
|
+
"56": "Collider",
|
|
35
|
+
"57": "Joint",
|
|
36
|
+
"58": "CircleCollider2D",
|
|
37
|
+
"59": "HingeJoint",
|
|
38
|
+
"60": "PolygonCollider2D",
|
|
39
|
+
"61": "BoxCollider2D",
|
|
40
|
+
"62": "PhysicsMaterial2D",
|
|
41
|
+
"64": "MeshCollider",
|
|
42
|
+
"65": "BoxCollider",
|
|
43
|
+
"66": "CompositeCollider2D",
|
|
44
|
+
"68": "EdgeCollider2D",
|
|
45
|
+
"70": "CapsuleCollider2D",
|
|
46
|
+
"72": "ComputeShader",
|
|
47
|
+
"74": "AnimationClip",
|
|
48
|
+
"75": "ConstantForce",
|
|
49
|
+
"78": "TagManager",
|
|
50
|
+
"81": "AudioListener",
|
|
51
|
+
"82": "AudioSource",
|
|
52
|
+
"83": "AudioClip",
|
|
53
|
+
"84": "RenderTexture",
|
|
54
|
+
"86": "CustomRenderTexture",
|
|
55
|
+
"89": "Cubemap",
|
|
56
|
+
"90": "Avatar",
|
|
57
|
+
"91": "AnimatorController",
|
|
58
|
+
"93": "RuntimeAnimatorController",
|
|
59
|
+
"94": "ShaderNameRegistry",
|
|
60
|
+
"95": "Animator",
|
|
61
|
+
"96": "TrailRenderer",
|
|
62
|
+
"98": "DelayedCallManager",
|
|
63
|
+
"102": "TextMesh",
|
|
64
|
+
"104": "RenderSettings",
|
|
65
|
+
"108": "Light",
|
|
66
|
+
"109": "ShaderInclude",
|
|
67
|
+
"110": "BaseAnimationTrack",
|
|
68
|
+
"111": "Animation",
|
|
69
|
+
"114": "MonoBehaviour",
|
|
70
|
+
"115": "MonoScript",
|
|
71
|
+
"116": "MonoManager",
|
|
72
|
+
"117": "Texture3D",
|
|
73
|
+
"118": "NewAnimationTrack",
|
|
74
|
+
"119": "Projector",
|
|
75
|
+
"120": "LineRenderer",
|
|
76
|
+
"121": "Flare",
|
|
77
|
+
"122": "Halo",
|
|
78
|
+
"123": "LensFlare",
|
|
79
|
+
"124": "FlareLayer",
|
|
80
|
+
"126": "NavMeshProjectSettings",
|
|
81
|
+
"128": "Font",
|
|
82
|
+
"129": "PlayerSettings",
|
|
83
|
+
"130": "NamedObject",
|
|
84
|
+
"134": "PhysicsMaterial",
|
|
85
|
+
"135": "SphereCollider",
|
|
86
|
+
"136": "CapsuleCollider",
|
|
87
|
+
"137": "SkinnedMeshRenderer",
|
|
88
|
+
"138": "FixedJoint",
|
|
89
|
+
"141": "BuildSettings",
|
|
90
|
+
"142": "AssetBundle",
|
|
91
|
+
"143": "CharacterController",
|
|
92
|
+
"144": "CharacterJoint",
|
|
93
|
+
"145": "SpringJoint",
|
|
94
|
+
"146": "WheelCollider",
|
|
95
|
+
"147": "ResourceManager",
|
|
96
|
+
"150": "PreloadData",
|
|
97
|
+
"152": "MovieTexture",
|
|
98
|
+
"153": "ConfigurableJoint",
|
|
99
|
+
"154": "TerrainCollider",
|
|
100
|
+
"156": "TerrainData",
|
|
101
|
+
"157": "LightmapSettings",
|
|
102
|
+
"158": "WebCamTexture",
|
|
103
|
+
"159": "EditorSettings",
|
|
104
|
+
"162": "EditorUserSettings",
|
|
105
|
+
"164": "AudioReverbFilter",
|
|
106
|
+
"165": "AudioHighPassFilter",
|
|
107
|
+
"166": "AudioChorusFilter",
|
|
108
|
+
"167": "AudioReverbZone",
|
|
109
|
+
"168": "AudioEchoFilter",
|
|
110
|
+
"169": "AudioLowPassFilter",
|
|
111
|
+
"170": "AudioDistortionFilter",
|
|
112
|
+
"171": "SparseTexture",
|
|
113
|
+
"180": "AudioBehaviour",
|
|
114
|
+
"181": "AudioFilter",
|
|
115
|
+
"182": "WindZone",
|
|
116
|
+
"183": "Cloth",
|
|
117
|
+
"184": "SubstanceArchive",
|
|
118
|
+
"185": "ProceduralMaterial",
|
|
119
|
+
"186": "ProceduralTexture",
|
|
120
|
+
"187": "Texture2DArray",
|
|
121
|
+
"188": "CubemapArray",
|
|
122
|
+
"191": "OffMeshLink",
|
|
123
|
+
"192": "OcclusionArea",
|
|
124
|
+
"193": "Tree",
|
|
125
|
+
"195": "NavMeshAgent",
|
|
126
|
+
"196": "NavMeshSettings",
|
|
127
|
+
"198": "ParticleSystem",
|
|
128
|
+
"199": "ParticleSystemRenderer",
|
|
129
|
+
"200": "ShaderVariantCollection",
|
|
130
|
+
"205": "LODGroup",
|
|
131
|
+
"206": "BlendTree",
|
|
132
|
+
"207": "Motion",
|
|
133
|
+
"208": "NavMeshObstacle",
|
|
134
|
+
"210": "SortingGroup",
|
|
135
|
+
"212": "SpriteRenderer",
|
|
136
|
+
"213": "Sprite",
|
|
137
|
+
"214": "CachedSpriteAtlas",
|
|
138
|
+
"215": "ReflectionProbe",
|
|
139
|
+
"218": "Terrain",
|
|
140
|
+
"220": "LightProbeGroup",
|
|
141
|
+
"221": "AnimatorOverrideController",
|
|
142
|
+
"222": "CanvasRenderer",
|
|
143
|
+
"223": "Canvas",
|
|
144
|
+
"224": "RectTransform",
|
|
145
|
+
"225": "CanvasGroup",
|
|
146
|
+
"226": "BillboardAsset",
|
|
147
|
+
"227": "BillboardRenderer",
|
|
148
|
+
"228": "SpeedTreeWindAsset",
|
|
149
|
+
"229": "AnchoredJoint2D",
|
|
150
|
+
"230": "Joint2D",
|
|
151
|
+
"231": "SpringJoint2D",
|
|
152
|
+
"232": "DistanceJoint2D",
|
|
153
|
+
"233": "HingeJoint2D",
|
|
154
|
+
"234": "SliderJoint2D",
|
|
155
|
+
"235": "WheelJoint2D",
|
|
156
|
+
"236": "ClusterInputManager",
|
|
157
|
+
"237": "BaseVideoTexture",
|
|
158
|
+
"238": "NavMeshData",
|
|
159
|
+
"240": "AudioMixer",
|
|
160
|
+
"241": "AudioMixerController",
|
|
161
|
+
"243": "AudioMixerGroupController",
|
|
162
|
+
"244": "AudioMixerEffectController",
|
|
163
|
+
"245": "AudioMixerSnapshotController",
|
|
164
|
+
"246": "PhysicsUpdateBehaviour2D",
|
|
165
|
+
"247": "ConstantForce2D",
|
|
166
|
+
"248": "Effector2D",
|
|
167
|
+
"249": "AreaEffector2D",
|
|
168
|
+
"250": "PointEffector2D",
|
|
169
|
+
"251": "PlatformEffector2D",
|
|
170
|
+
"252": "SurfaceEffector2D",
|
|
171
|
+
"253": "BuoyancyEffector2D",
|
|
172
|
+
"254": "RelativeJoint2D",
|
|
173
|
+
"255": "FixedJoint2D",
|
|
174
|
+
"256": "FrictionJoint2D",
|
|
175
|
+
"257": "TargetJoint2D",
|
|
176
|
+
"258": "LightProbes",
|
|
177
|
+
"259": "LightProbeProxyVolume",
|
|
178
|
+
"271": "SampleClip",
|
|
179
|
+
"272": "AudioMixerSnapshot",
|
|
180
|
+
"273": "AudioMixerGroup",
|
|
181
|
+
"290": "AssetBundleManifest",
|
|
182
|
+
"300": "RuntimeInitializeOnLoadManager",
|
|
183
|
+
"310": "UnityConnectSettings",
|
|
184
|
+
"319": "AvatarMask",
|
|
185
|
+
"320": "PlayableDirector",
|
|
186
|
+
"328": "VideoPlayer",
|
|
187
|
+
"329": "VideoClip",
|
|
188
|
+
"330": "ParticleSystemForceField",
|
|
189
|
+
"331": "SpriteMask",
|
|
190
|
+
"363": "OcclusionCullingData",
|
|
191
|
+
"900": "MarshallingTestObject",
|
|
192
|
+
"1001": "PrefabInstance",
|
|
193
|
+
"1002": "EditorExtensionImpl",
|
|
194
|
+
"1003": "AssetImporter",
|
|
195
|
+
"1005": "Mesh3DSImporter",
|
|
196
|
+
"1006": "TextureImporter",
|
|
197
|
+
"1007": "ShaderImporter",
|
|
198
|
+
"1008": "ComputeShaderImporter",
|
|
199
|
+
"1020": "AudioImporter",
|
|
200
|
+
"1026": "HierarchyState",
|
|
201
|
+
"1028": "AssetMetaData",
|
|
202
|
+
"1029": "DefaultAsset",
|
|
203
|
+
"1030": "DefaultImporter",
|
|
204
|
+
"1031": "TextScriptImporter",
|
|
205
|
+
"1032": "SceneAsset",
|
|
206
|
+
"1034": "NativeFormatImporter",
|
|
207
|
+
"1035": "MonoImporter",
|
|
208
|
+
"1038": "LibraryAssetImporter",
|
|
209
|
+
"1040": "ModelImporter",
|
|
210
|
+
"1041": "FBXImporter",
|
|
211
|
+
"1042": "TrueTypeFontImporter",
|
|
212
|
+
"1045": "EditorBuildSettings",
|
|
213
|
+
"1048": "InspectorExpandedState",
|
|
214
|
+
"1049": "AnnotationManager",
|
|
215
|
+
"1050": "PluginImporter",
|
|
216
|
+
"1051": "EditorUserBuildSettings",
|
|
217
|
+
"1055": "IHVImageFormatImporter",
|
|
218
|
+
"1101": "AnimatorStateTransition",
|
|
219
|
+
"1102": "AnimatorState",
|
|
220
|
+
"1105": "HumanTemplate",
|
|
221
|
+
"1107": "AnimatorStateMachine",
|
|
222
|
+
"1108": "PreviewAnimationClip",
|
|
223
|
+
"1109": "AnimatorTransition",
|
|
224
|
+
"1110": "SpeedTreeImporter",
|
|
225
|
+
"1111": "AnimatorTransitionBase",
|
|
226
|
+
"1112": "SubstanceImporter",
|
|
227
|
+
"1113": "LightmapParameters",
|
|
228
|
+
"1120": "LightingDataAsset",
|
|
229
|
+
"1124": "SketchUpImporter",
|
|
230
|
+
"1125": "BuildReport",
|
|
231
|
+
"1126": "PackedAssets",
|
|
232
|
+
"1127": "VideoClipImporter",
|
|
233
|
+
"100000": "int",
|
|
234
|
+
"100001": "bool",
|
|
235
|
+
"100002": "float",
|
|
236
|
+
"100003": "MonoObject",
|
|
237
|
+
"100004": "Collision",
|
|
238
|
+
"100005": "Vector3f",
|
|
239
|
+
"100006": "RootMotionData",
|
|
240
|
+
"100007": "Collision2D",
|
|
241
|
+
"100008": "AudioMixerLiveUpdateFloat",
|
|
242
|
+
"100009": "AudioMixerLiveUpdateBool",
|
|
243
|
+
"100010": "Polygon2D",
|
|
244
|
+
"100011": "void",
|
|
245
|
+
"19719996": "TilemapCollider2D",
|
|
246
|
+
"41386430": "ImportLog",
|
|
247
|
+
"55640938": "GraphicsStateCollection",
|
|
248
|
+
"73398921": "VFXRenderer",
|
|
249
|
+
"156049354": "Grid",
|
|
250
|
+
"156483287": "ScenesUsingAssets",
|
|
251
|
+
"171741748": "ArticulationBody",
|
|
252
|
+
"181963792": "Preset",
|
|
253
|
+
"285090594": "IConstraint",
|
|
254
|
+
"294290339": "AssemblyDefinitionReferenceImporter",
|
|
255
|
+
"355983997": "AudioResource",
|
|
256
|
+
"369655926": "AssetImportInProgressProxy",
|
|
257
|
+
"382020655": "PluginBuildInfo",
|
|
258
|
+
"387306366": "MemorySettings",
|
|
259
|
+
"403037116": "BuildMetaDataImporter",
|
|
260
|
+
"403037117": "BuildInstructionImporter",
|
|
261
|
+
"426301858": "EditorProjectAccess",
|
|
262
|
+
"468431735": "PrefabImporter",
|
|
263
|
+
"483693784": "TilemapRenderer",
|
|
264
|
+
"612988286": "SpriteAtlasAsset",
|
|
265
|
+
"638013454": "SpriteAtlasDatabase",
|
|
266
|
+
"641289076": "AudioBuildInfo",
|
|
267
|
+
"644342135": "CachedSpriteAtlasRuntimeData",
|
|
268
|
+
"655991488": "MultiplayerManager",
|
|
269
|
+
"662584278": "AssemblyDefinitionReferenceAsset",
|
|
270
|
+
"668709126": "BuiltAssetBundleInfoSet",
|
|
271
|
+
"687078895": "SpriteAtlas",
|
|
272
|
+
"702665669": "DifferentMarshallingTestObject",
|
|
273
|
+
"747330370": "RayTracingShaderImporter",
|
|
274
|
+
"780535461": "BuildArchiveImporter",
|
|
275
|
+
"815301076": "PreviewImporter",
|
|
276
|
+
"825902497": "RayTracingShader",
|
|
277
|
+
"850595691": "LightingSettings",
|
|
278
|
+
"877146078": "PlatformModuleSetup",
|
|
279
|
+
"890905787": "VersionControlSettings",
|
|
280
|
+
"893571522": "CustomCollider2D",
|
|
281
|
+
"895512359": "AimConstraint",
|
|
282
|
+
"937362698": "VFXManager",
|
|
283
|
+
"947337230": "RoslynAnalyzerConfigAsset",
|
|
284
|
+
"954905827": "RuleSetFileAsset",
|
|
285
|
+
"994735392": "VisualEffectSubgraph",
|
|
286
|
+
"994735403": "VisualEffectSubgraphOperator",
|
|
287
|
+
"994735404": "VisualEffectSubgraphBlock",
|
|
288
|
+
"1001480554": "Prefab",
|
|
289
|
+
"1027052791": "LocalizationImporter",
|
|
290
|
+
"1114811875": "ReferencesArtifactGenerator",
|
|
291
|
+
"1152215463": "AssemblyDefinitionAsset",
|
|
292
|
+
"1154873562": "SceneVisibilityState",
|
|
293
|
+
"1183024399": "LookAtConstraint",
|
|
294
|
+
"1210832254": "SpriteAtlasImporter",
|
|
295
|
+
"1223240404": "MultiArtifactTestImporter",
|
|
296
|
+
"1233149941": "AudioContainerElement",
|
|
297
|
+
"1268269756": "GameObjectRecorder",
|
|
298
|
+
"1307931743": "AudioRandomContainer",
|
|
299
|
+
"1325145578": "LightingDataAssetParent",
|
|
300
|
+
"1386491679": "PresetManager",
|
|
301
|
+
"1403656975": "StreamingManager",
|
|
302
|
+
"1480428607": "LowerResBlitTexture",
|
|
303
|
+
"1521398425": "VideoBuildInfo",
|
|
304
|
+
"1541671625": "C4DImporter",
|
|
305
|
+
"1542919678": "StreamingController",
|
|
306
|
+
"1557264870": "ShaderContainer",
|
|
307
|
+
"1597193336": "RoslynAdditionalFileAsset",
|
|
308
|
+
"1642787288": "RoslynAdditionalFileImporter",
|
|
309
|
+
"1652712579": "MultiplayerRolesData",
|
|
310
|
+
"1660057539": "SceneRoots",
|
|
311
|
+
"1731078267": "BrokenPrefabAsset",
|
|
312
|
+
"1736697216": "AndroidAssetPackImporter",
|
|
313
|
+
"1740304944": "VulkanDeviceFilterLists",
|
|
314
|
+
"1742807556": "GridLayout",
|
|
315
|
+
"1766753193": "AssemblyDefinitionImporter",
|
|
316
|
+
"1773428102": "ParentConstraint",
|
|
317
|
+
"1777034230": "RuleSetFileImporter",
|
|
318
|
+
"1818360608": "PositionConstraint",
|
|
319
|
+
"1818360609": "RotationConstraint",
|
|
320
|
+
"1818360610": "ScaleConstraint",
|
|
321
|
+
"1839735485": "Tilemap",
|
|
322
|
+
"1896753125": "PackageManifest",
|
|
323
|
+
"1896753126": "PackageManifestImporter",
|
|
324
|
+
"1903396204": "RoslynAnalyzerConfigImporter",
|
|
325
|
+
"1931382933": "UIRenderer",
|
|
326
|
+
"1953259897": "TerrainLayer",
|
|
327
|
+
"1971053207": "SpriteShapeRenderer",
|
|
328
|
+
"2058629509": "VisualEffectAsset",
|
|
329
|
+
"2058629510": "VisualEffectImporter",
|
|
330
|
+
"2058629511": "VisualEffectResource",
|
|
331
|
+
"2059678085": "VisualEffectObject",
|
|
332
|
+
"2083052967": "VisualEffect",
|
|
333
|
+
"2083778819": "LocalizationAsset",
|
|
334
|
+
"2089858483": "ScriptedImporter",
|
|
335
|
+
"2103361453": "ShaderIncludeImporter"
|
|
336
|
+
}
|
unityflow/diff.py
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"""Unity Prefab Diff Utilities.
|
|
2
|
+
|
|
3
|
+
Provides meaningful diff output by normalizing files before comparison,
|
|
4
|
+
eliminating noise from Unity's non-deterministic serialization.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import difflib
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from enum import Enum
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
from unityflow.normalizer import UnityPrefabNormalizer
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class DiffFormat(Enum):
|
|
18
|
+
"""Output format for diff."""
|
|
19
|
+
|
|
20
|
+
UNIFIED = "unified"
|
|
21
|
+
CONTEXT = "context"
|
|
22
|
+
SIDE_BY_SIDE = "side-by-side"
|
|
23
|
+
SUMMARY = "summary"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class DiffResult:
|
|
28
|
+
"""Result of a diff operation."""
|
|
29
|
+
|
|
30
|
+
old_path: str
|
|
31
|
+
new_path: str
|
|
32
|
+
old_content: str
|
|
33
|
+
new_content: str
|
|
34
|
+
has_changes: bool
|
|
35
|
+
diff_lines: list[str]
|
|
36
|
+
|
|
37
|
+
def __str__(self) -> str:
|
|
38
|
+
return "\n".join(self.diff_lines)
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def additions(self) -> int:
|
|
42
|
+
"""Count of added lines."""
|
|
43
|
+
return sum(1 for line in self.diff_lines if line.startswith("+") and not line.startswith("+++"))
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def deletions(self) -> int:
|
|
47
|
+
"""Count of deleted lines."""
|
|
48
|
+
return sum(1 for line in self.diff_lines if line.startswith("-") and not line.startswith("---"))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
class PrefabDiff:
|
|
52
|
+
"""Diff utility for Unity prefab files."""
|
|
53
|
+
|
|
54
|
+
def __init__(
|
|
55
|
+
self,
|
|
56
|
+
normalize: bool = True,
|
|
57
|
+
context_lines: int = 3,
|
|
58
|
+
format: DiffFormat = DiffFormat.UNIFIED,
|
|
59
|
+
):
|
|
60
|
+
"""Initialize the diff utility.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
normalize: Whether to normalize files before diffing
|
|
64
|
+
context_lines: Number of context lines to show
|
|
65
|
+
format: Output format
|
|
66
|
+
"""
|
|
67
|
+
self.normalize = normalize
|
|
68
|
+
self.context_lines = context_lines
|
|
69
|
+
self.format = format
|
|
70
|
+
self._normalizer = UnityPrefabNormalizer() if normalize else None
|
|
71
|
+
|
|
72
|
+
def diff_files(
|
|
73
|
+
self,
|
|
74
|
+
old_path: str | Path,
|
|
75
|
+
new_path: str | Path,
|
|
76
|
+
) -> DiffResult:
|
|
77
|
+
"""Diff two Unity YAML files.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
old_path: Path to the old/original file
|
|
81
|
+
new_path: Path to the new/modified file
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
DiffResult containing the diff output
|
|
85
|
+
"""
|
|
86
|
+
old_path = Path(old_path)
|
|
87
|
+
new_path = Path(new_path)
|
|
88
|
+
|
|
89
|
+
# Read and optionally normalize
|
|
90
|
+
if self.normalize and self._normalizer:
|
|
91
|
+
old_content = self._normalizer.normalize_file(old_path)
|
|
92
|
+
new_content = self._normalizer.normalize_file(new_path)
|
|
93
|
+
else:
|
|
94
|
+
old_content = old_path.read_text(encoding="utf-8")
|
|
95
|
+
new_content = new_path.read_text(encoding="utf-8")
|
|
96
|
+
|
|
97
|
+
return self.diff_content(
|
|
98
|
+
old_content,
|
|
99
|
+
new_content,
|
|
100
|
+
old_label=str(old_path),
|
|
101
|
+
new_label=str(new_path),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
def diff_content(
|
|
105
|
+
self,
|
|
106
|
+
old_content: str,
|
|
107
|
+
new_content: str,
|
|
108
|
+
old_label: str = "old",
|
|
109
|
+
new_label: str = "new",
|
|
110
|
+
) -> DiffResult:
|
|
111
|
+
"""Diff two content strings.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
old_content: The old/original content
|
|
115
|
+
new_content: The new/modified content
|
|
116
|
+
old_label: Label for the old content
|
|
117
|
+
new_label: Label for the new content
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
DiffResult containing the diff output
|
|
121
|
+
"""
|
|
122
|
+
old_lines = old_content.splitlines(keepends=True)
|
|
123
|
+
new_lines = new_content.splitlines(keepends=True)
|
|
124
|
+
|
|
125
|
+
has_changes = old_content != new_content
|
|
126
|
+
|
|
127
|
+
if self.format == DiffFormat.UNIFIED:
|
|
128
|
+
diff_lines = list(
|
|
129
|
+
difflib.unified_diff(
|
|
130
|
+
old_lines,
|
|
131
|
+
new_lines,
|
|
132
|
+
fromfile=old_label,
|
|
133
|
+
tofile=new_label,
|
|
134
|
+
n=self.context_lines,
|
|
135
|
+
)
|
|
136
|
+
)
|
|
137
|
+
elif self.format == DiffFormat.CONTEXT:
|
|
138
|
+
diff_lines = list(
|
|
139
|
+
difflib.context_diff(
|
|
140
|
+
old_lines,
|
|
141
|
+
new_lines,
|
|
142
|
+
fromfile=old_label,
|
|
143
|
+
tofile=new_label,
|
|
144
|
+
n=self.context_lines,
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
elif self.format == DiffFormat.SUMMARY:
|
|
148
|
+
diff_lines = self._generate_summary(old_lines, new_lines, old_label, new_label)
|
|
149
|
+
else:
|
|
150
|
+
diff_lines = list(
|
|
151
|
+
difflib.unified_diff(
|
|
152
|
+
old_lines,
|
|
153
|
+
new_lines,
|
|
154
|
+
fromfile=old_label,
|
|
155
|
+
tofile=new_label,
|
|
156
|
+
n=self.context_lines,
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
# Strip trailing newlines from diff lines for cleaner output
|
|
161
|
+
diff_lines = [line.rstrip("\n") for line in diff_lines]
|
|
162
|
+
|
|
163
|
+
return DiffResult(
|
|
164
|
+
old_path=old_label,
|
|
165
|
+
new_path=new_label,
|
|
166
|
+
old_content=old_content,
|
|
167
|
+
new_content=new_content,
|
|
168
|
+
has_changes=has_changes,
|
|
169
|
+
diff_lines=diff_lines,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
def _generate_summary(
|
|
173
|
+
self,
|
|
174
|
+
old_lines: list[str],
|
|
175
|
+
new_lines: list[str],
|
|
176
|
+
old_label: str,
|
|
177
|
+
new_label: str,
|
|
178
|
+
) -> list[str]:
|
|
179
|
+
"""Generate a summary of changes."""
|
|
180
|
+
matcher = difflib.SequenceMatcher(None, old_lines, new_lines)
|
|
181
|
+
opcodes = matcher.get_opcodes()
|
|
182
|
+
|
|
183
|
+
summary = [f"Comparing {old_label} -> {new_label}", ""]
|
|
184
|
+
|
|
185
|
+
additions = 0
|
|
186
|
+
deletions = 0
|
|
187
|
+
changes = 0
|
|
188
|
+
|
|
189
|
+
for tag, i1, i2, j1, j2 in opcodes:
|
|
190
|
+
if tag == "insert":
|
|
191
|
+
additions += j2 - j1
|
|
192
|
+
elif tag == "delete":
|
|
193
|
+
deletions += i2 - i1
|
|
194
|
+
elif tag == "replace":
|
|
195
|
+
changes += max(i2 - i1, j2 - j1)
|
|
196
|
+
|
|
197
|
+
summary.append(f" Lines added: {additions}")
|
|
198
|
+
summary.append(f" Lines deleted: {deletions}")
|
|
199
|
+
summary.append(f" Lines changed: {changes}")
|
|
200
|
+
|
|
201
|
+
if additions == 0 and deletions == 0 and changes == 0:
|
|
202
|
+
summary.append("")
|
|
203
|
+
summary.append("No changes detected.")
|
|
204
|
+
else:
|
|
205
|
+
summary.append("")
|
|
206
|
+
summary.append("Changed sections:")
|
|
207
|
+
for tag, i1, i2, j1, j2 in opcodes:
|
|
208
|
+
if tag != "equal":
|
|
209
|
+
summary.append(f" - {tag}: lines {i1+1}-{i2} -> {j1+1}-{j2}")
|
|
210
|
+
|
|
211
|
+
return summary
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def diff_prefabs(
|
|
215
|
+
old_path: str | Path,
|
|
216
|
+
new_path: str | Path,
|
|
217
|
+
normalize: bool = True,
|
|
218
|
+
format: DiffFormat = DiffFormat.UNIFIED,
|
|
219
|
+
context_lines: int = 3,
|
|
220
|
+
) -> DiffResult:
|
|
221
|
+
"""Convenience function to diff two prefab files.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
old_path: Path to the old file
|
|
225
|
+
new_path: Path to the new file
|
|
226
|
+
normalize: Whether to normalize before diffing
|
|
227
|
+
format: Output format
|
|
228
|
+
context_lines: Number of context lines
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
DiffResult containing the diff
|
|
232
|
+
"""
|
|
233
|
+
differ = PrefabDiff(normalize=normalize, format=format, context_lines=context_lines)
|
|
234
|
+
return differ.diff_files(old_path, new_path)
|