Skip to content
quarry Artifact [9b864b6e16]
Login

Artifact [9b864b6e16]

Artifact 9b864b6e1631555d0aff548a83a43f45eda376d64200de0b1a4dd1ff4ac29389:


package main

import (
	"log"

	"craftdesign.group/quarry/internal/index"
	"craftdesign.group/quarry/internal/markup"
)

// closePage is how many new check-ins one read of the sweep takes; a
// larger push is walked a page at a time within the same pass.
const closePage = 50

// closeSweep closes the tickets new default-branch check-ins say they
// close (quarry#298), fossil-style: "closes #12" in a check-in comment
// does what it does in a landing's message. Runs after every fold, on
// the lease holder only.
//
// A durable watermark bounds what is new, so the history a repository
// arrives with — a mirror's, or anything folded before this sweep
// existed — is baselined at first sight, never read as a list of
// closes. A per-check-in mark makes each close happen once across
// restarts and re-folds. A landing's own merge is left to the landing,
// whose accept closes what it named; a tracking mirror's tracker
// belongs to its upstream and is not written.
func (rg *registrar) closeSweep(name string, ix *index.Index) {
	if rg.odb == nil || rg.deps == nil || ix == nil {
		return
	}
	if rg.deps.Mirrors != nil {
		if m, ok, err := rg.deps.Mirrors.MirrorFor(name); err != nil || (ok && m.Enabled) {
			return
		}
	}
	watch, seen := rg.odb.CloseWatch(name)
	if !seen {
		if tip, err := ix.CheckinsAfter("", 1); err == nil && len(tip) == 1 {
			_ = rg.odb.SetCloseWatch(name, tip[0].Hash)
		}
		return
	}
	// A watermark the index does not hold (a reindex part-way through)
	// would read as "only the newest check-in is new", and that one may
	// be history. Wait for the index to catch up instead.
	if known, err := ix.BranchOf([]string{watch}); err != nil || known[watch] == "" {
		return
	}
	branch := ix.DefaultBranch()
	for {
		fresh, err := ix.CheckinsAfter(watch, closePage)
		if err != nil || len(fresh) == 0 {
			return
		}
		for _, c := range fresh {
			if c.Branch == branch {
				rg.closeFrom(name, ix, c)
			}
		}
		watch = fresh[len(fresh)-1].Hash
		if err := rg.odb.SetCloseWatch(name, watch); err != nil {
			log.Printf("close: %s: watermark: %v", name, err)
			return
		}
		if len(fresh) < closePage {
			return
		}
	}
}

// closeFrom closes what one default-branch check-in names, once.
func (rg *registrar) closeFrom(name string, ix *index.Index, c index.TimelineEntry) {
	if len(markup.ClosingRefs(c.Comment)) == 0 {
		return
	}
	if done, err := rg.odb.CheckinClosed(name, c.Hash); err != nil || done {
		return
	}
	if merge, err := ix.IsLandingMerge(c.Hash); err != nil || merge {
		return
	}
	rg.deps.CloseFromCheckin(name, c)
	if err := rg.odb.MarkCheckinClosed(name, c.Hash); err != nil {
		log.Printf("close: %s %.12s: mark: %v", name, c.Hash, err)
	}
}