Commit cce1481
Eric Bower
·
2026-05-11 23:35:11 -0400 EDT
parent a36f4fa
feat: only write commit if file is missing feat: only write tree files if shasum is different
1 files changed,
+58,
-4
M
main.go
M
main.go
+58,
-4
| ... | ... | @@ -2,10 +2,12 @@ package main | |
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | 4 | "bytes" | |
| 5 | + | "crypto/sha256" | |
| 5 | 6 | "embed" | |
| 6 | 7 | "flag" | |
| 7 | 8 | "fmt" | |
| 8 | 9 | "html/template" | |
| 10 | + | "io" | |
| 9 | 11 | "log/slog" | |
| 10 | 12 | "math" | |
| 11 | 13 | "os" |
| ... | ... | @@ -332,6 +334,47 @@ func (c *Config) writeHtml(writeData *WriteData) { | |
| 332 | 334 | bail(err) | |
| 333 | 335 | } | |
| 334 | 336 | ||
| 337 | + | // writeHtmlIfChanged renders a template and only writes if content hash differs from existing file | |
| 338 | + | func (c *Config) writeHtmlIfChanged(writeData *WriteData) { | |
| 339 | + | ts, err := template.ParseFS( | |
| 340 | + | embedFS, | |
| 341 | + | writeData.Template, | |
| 342 | + | "html/header.partial.tmpl", | |
| 343 | + | "html/footer.partial.tmpl", | |
| 344 | + | "html/base.layout.tmpl", | |
| 345 | + | ) | |
| 346 | + | bail(err) | |
| 347 | + | ||
| 348 | + | // render to buffer first | |
| 349 | + | var buf bytes.Buffer | |
| 350 | + | err = ts.Execute(&buf, writeData.Data) | |
| 351 | + | bail(err) | |
| 352 | + | ||
| 353 | + | dir := filepath.Join(c.Outdir, writeData.Subdir) | |
| 354 | + | err = os.MkdirAll(dir, os.ModePerm) | |
| 355 | + | bail(err) | |
| 356 | + | ||
| 357 | + | fp := filepath.Join(dir, writeData.Filename) | |
| 358 | + | ||
| 359 | + | // compute hash of new content | |
| 360 | + | newHash := sha256.Sum256(buf.Bytes()) | |
| 361 | + | ||
| 362 | + | // compare with existing file | |
| 363 | + | if f, err := os.Open(fp); err == nil { | |
| 364 | + | defer f.Close() | |
| 365 | + | h := sha256.New() | |
| 366 | + | if _, err := io.Copy(h, f); err == nil { | |
| 367 | + | if bytes.Equal(h.Sum(nil), newHash[:]) { | |
| 368 | + | return // unchanged, skip | |
| 369 | + | } | |
| 370 | + | } | |
| 371 | + | } | |
| 372 | + | ||
| 373 | + | c.Logger.Info("writing", "filepath", fp) | |
| 374 | + | err = os.WriteFile(fp, buf.Bytes(), 0644) | |
| 375 | + | bail(err) | |
| 376 | + | } | |
| 377 | + | ||
| 335 | 378 | func (c *Config) copyStatic(dir string) error { | |
| 336 | 379 | entries, err := staticFS.ReadDir(dir) | |
| 337 | 380 | bail(err) |
| ... | ... | @@ -405,6 +448,7 @@ func (c *Config) writeRefs(data *PageData, refs []*RefInfo) { | |
| 405 | 448 | } | |
| 406 | 449 | ||
| 407 | 450 | func (c *Config) writeHTMLTreeFile(pageData *PageData, treeItem *TreeItem) string { | |
| 451 | + | d := filepath.Dir(treeItem.Path) | |
| 408 | 452 | readme := "" | |
| 409 | 453 | b, err := treeItem.Entry.Blob().Bytes() | |
| 410 | 454 | bail(err) |
| ... | ... | @@ -419,15 +463,13 @@ func (c *Config) writeHTMLTreeFile(pageData *PageData, treeItem *TreeItem) strin | |
| 419 | 463 | bail(err) | |
| 420 | 464 | } | |
| 421 | 465 | ||
| 422 | - | d := filepath.Dir(treeItem.Path) | |
| 423 | - | ||
| 424 | 466 | nameLower := strings.ToLower(treeItem.Entry.Name()) | |
| 425 | 467 | summary := readmeFile(pageData.Repo) | |
| 426 | 468 | if d == "." && nameLower == summary { | |
| 427 | 469 | readme = contents | |
| 428 | 470 | } | |
| 429 | 471 | ||
| 430 | - | c.writeHtml(&WriteData{ | |
| 472 | + | c.writeHtmlIfChanged(&WriteData{ | |
| 431 | 473 | Filename: fmt.Sprintf("%s.html", treeItem.Entry.Name()), | |
| 432 | 474 | Template: "html/file.page.tmpl", | |
| 433 | 475 | Data: &FilePageData{ |
| ... | ... | @@ -450,12 +492,22 @@ func (c *Config) writeLogDiff(repo *git.Repository, pageData *PageData, commit * | |
| 450 | 492 | if hasCommit { | |
| 451 | 493 | c.Logger.Info("commit file already generated, skipping", "commitID", getShortID(commitID)) | |
| 452 | 494 | return | |
| 453 | - | } else { | |
| 495 | + | } | |
| 496 | + | ||
| 497 | + | // skip if output file already exists from a previous run | |
| 498 | + | commitPath := filepath.Join(c.Outdir, "commits", commitID+".html") | |
| 499 | + | if _, err := os.Stat(commitPath); err == nil { | |
| 500 | + | c.Logger.Info("commit file exists, skipping", "commitID", getShortID(commitID)) | |
| 454 | 501 | c.Mutex.Lock() | |
| 455 | 502 | c.Cache[commitID] = true | |
| 456 | 503 | c.Mutex.Unlock() | |
| 504 | + | return | |
| 457 | 505 | } | |
| 458 | 506 | ||
| 507 | + | c.Mutex.Lock() | |
| 508 | + | c.Cache[commitID] = true | |
| 509 | + | c.Mutex.Unlock() | |
| 510 | + | ||
| 459 | 511 | diff, err := repo.Diff(commitID, 0, 0, 0, git.DiffOptions{}) | |
| 460 | 512 | bail(err) | |
| 461 | 513 |