(files []*gitdiff.File)
| 259 | } |
| 260 | |
| 261 | func buildFileTree(files []*gitdiff.File) []*templates.FileTree { |
| 262 | // Use a synthetic root (not rendered), collect top-level nodes in a map first. |
| 263 | root := &templates.FileTree{IsDir: true, Name: "", Path: "", Children: nil} |
| 264 | |
| 265 | for _, f := range files { |
| 266 | path := f.NewName |
| 267 | if f.IsDelete { |
| 268 | path = f.OldName |
| 269 | } |
| 270 | |
| 271 | path = filepath.ToSlash(strings.TrimPrefix(path, "./")) |
| 272 | if path == "" { |
| 273 | continue |
| 274 | } |
| 275 | parts := strings.Split(path, "/") |
| 276 | |
| 277 | parent := root |
| 278 | accum := "" |
| 279 | if len(parts) > 1 { |
| 280 | for i := 0; i < len(parts)-1; i++ { |
| 281 | if accum == "" { |
| 282 | accum = parts[i] |
| 283 | } else { |
| 284 | accum = accum + "/" + parts[i] |
| 285 | } |
| 286 | parent = findOrCreateDir(parent, parts[i], accum) |
| 287 | } |
| 288 | } |
| 289 | |
| 290 | fileName := parts[len(parts)-1] |
| 291 | node := &templates.FileTree{ |
| 292 | Name: fileName, |
| 293 | Path: path, |
| 294 | IsDir: false, |
| 295 | IsNew: f.IsNew, |
| 296 | IsDelete: f.IsDelete, |
| 297 | IsRename: f.IsRename, |
| 298 | OldName: f.OldName, |
| 299 | NewName: f.NewName, |
| 300 | } |
| 301 | parent.Children = append(parent.Children, node) |
| 302 | } |
| 303 | |
| 304 | sortNode(root) |
| 305 | return root.Children |
| 306 | } |
| 307 | |
| 308 | func findOrCreateDir(parent *templates.FileTree, name, path string) *templates.FileTree { |
| 309 | for _, ch := range parent.Children { |
no test coverage detected