import { ASSET_FAMILIES } from './asset-naming' import type { AssetCategory, FileChange, PreparedAssetSummary } from './types' const ASSET_SECTION_ORDER: AssetCategory[] = [...ASSET_FAMILIES, 'assets'] function getChangePrefix(change: FileChange) { if (change === 'new') return '✅' if (change === 'changed') return '🔄' return null } function addGroupedAssetLine( grouped: Map, category: AssetCategory, line: string, ) { const current = grouped.get(category) || [] current.push(line) grouped.set(category, current) } /** * Build a formatted commit message based on the upload context. * * Symbols: * - ✅ = new file * - 🔄 = modified file * - ❌ = deleted file * - Unchanged files are omitted entirely */ export function buildCommitMessage( folderName: string, modelFilename: string, assetSummaries: PreparedAssetSummary[], isReplace: boolean, fileChanges: Map, deletedFileNames: string[], ): string { const title = isReplace ? `update: upload-gltf update -> ${folderName}` : `update: upload-gltf add a new model -> ${folderName}` const lines: string[] = [title, ''] const modelSummary = assetSummaries.find((asset) => asset.kind === 'model') const modelChange = fileChanges.get(modelFilename.toLowerCase()) if (modelChange === 'new') { lines.push('ðŸ“Ķ Model') lines.push(` ✅ ${modelFilename}${modelSummary?.compressed ? ' (compressed)' : ''}`) } else if (modelChange === 'changed') { lines.push('ðŸ“Ķ Model') lines.push(` 🔄 ${modelFilename}${modelSummary?.compressed ? ' (compressed)' : ''}`) } else if (modelChange === 'unchanged') { lines.push('ðŸ“Ķ Model') lines.push(` ↔ïļ ${modelFilename}${modelSummary?.compressed ? ' (compressed)' : ' (inchange)'}`) } const grouped = new Map() for (const asset of assetSummaries) { if (asset.kind === 'model' || !asset.category) continue const change = fileChanges.get(asset.filename.toLowerCase()) if (!change) continue const prefix = getChangePrefix(change) if (!prefix) continue addGroupedAssetLine( grouped, asset.category, ` ${prefix} ${asset.filename}${asset.compressed ? ' (compressed)' : ''}`, ) } const sectionTitles: Record = { color: 'ðŸŽĻ Textures (color)', diffuse: '🖌 Textures (diffuse)', roughness: 'ðŸŠķ Textures (roughness)', normal: '🧭 Textures (normal)', metalness: 'ðŸ”Đ Textures (metalness)', height: '⛰ Textures (height)', opacity: '🊟 Textures (opacity)', orm: 'ðŸ§ą Textures (orm)', ao: '🌑 Textures (ao)', assets: 'ðŸ§Đ Assets', } for (const category of ASSET_SECTION_ORDER) { const entries = grouped.get(category) if (!entries || entries.length === 0) continue lines.push('') lines.push(sectionTitles[category]) lines.push(...entries) } if (deletedFileNames.length > 0) { lines.push('') lines.push('🗑 Deleted') lines.push(...deletedFileNames.map((name) => ` ❌ ${name}`)) } return lines.join('\n') }