Skip to content
quarry Artifact [d4f0ad1c8a]
Login

Artifact [d4f0ad1c8a]

Artifact d4f0ad1c8a406b78e90a5befa199af957a05cfc107a63f3cfa7c24da28948114:


package web

import (
	"net/http"
	"net/url"
	"slices"

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

// stackCandidate is an open landing another may be stacked on.
type stackCandidate struct {
	ID     string
	Number int
	Title  string
	Branch string
}

// stackCandidates lists the open landings the landing id (on branch,
// aimed at target) may be stacked on: newest activity first, never
// itself or what it already targets, and never one whose strata already
// stands on it, which would make a loop. The op refuses those too; the
// list is so the page never offers what it would refuse.
func stackCandidates(req *http.Request, r *ops.Registry, repo, id, branch, target string) []stackCandidate {
	res, err := invoke(req.Context(), r, "landing.list", url.Values{
		"repo": {repo}, "state": {"open"}, "limit": {"200"}})
	if err != nil {
		return nil
	}
	var list struct {
		Landings []index.LandingSummary `json:"landings"`
	}
	remarshal(res, &list)
	var out []stackCandidate
	for _, l := range list.Landings {
		if l.ID == id || l.State != "open" || l.SupersededBy != "" || l.Branch == target || l.Branch == branch {
			continue
		}
		if _, through, ok := index.LandsOn(list.Landings, l.Branch); !ok || slices.Contains(through, branch) {
			continue
		}
		out = append(out, stackCandidate{ID: l.ID, Number: l.Number, Title: l.Title, Branch: l.Branch})
	}
	return out
}