mirror of
https://github.com/juanfont/headscale.git
synced 2026-09-26 18:24:54 +09:00
823db85509
`go get -u` takes the highest semver the proxy offers: a fork's stray tag sorting above its real branch, or a module that has moved and kept tagging under the old path. Resolving first refuses both, and names the compare link for every version that does move.
171 lines
3.8 KiB
Go
171 lines
3.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
)
|
|
|
|
// cmdPlan resolves every upstream the bump reads and prints the gap against
|
|
// what is committed. It writes nothing, so it is the safe way to ask "what
|
|
// would tonight's run do" before trusting the automation.
|
|
func cmdPlan(ctx context.Context) error {
|
|
r, err := openRepo(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, line := range planLines(ctx, r) {
|
|
fmt.Println(line) //nolint:forbidigo // plan output is the point
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func planLines(ctx context.Context, r *repo) []string {
|
|
lines := []string{"flake.lock: `nix flake update` moves nixpkgs, flake-utils and flake-checks"}
|
|
|
|
lines = append(lines, planBuilders(ctx, r)...)
|
|
lines = append(lines, planLockstep(ctx, r)...)
|
|
lines = append(lines, planImages(ctx, r)...)
|
|
|
|
if version, err := oapiVersion(r); err != nil { //nolint:noinlineerr
|
|
lines = append(lines, "oapi-codegen: "+err.Error())
|
|
} else if latest, err := latestVersion(ctx, "github.com/oapi-codegen/oapi-codegen/v2", version); err != nil { //nolint:noinlineerr
|
|
lines = append(lines, "oapi-codegen: "+err.Error())
|
|
} else {
|
|
lines = append(lines, gap("Makefile oapi-codegen", version, latest))
|
|
}
|
|
|
|
return lines
|
|
}
|
|
|
|
func planImages(ctx context.Context, r *repo) []string {
|
|
defs := imageBumps()
|
|
lines := make([]string, 0, len(defs))
|
|
|
|
for _, def := range defs {
|
|
have, err := currentImageRef(r, def)
|
|
if err != nil {
|
|
lines = append(lines, def.Name+": "+err.Error())
|
|
|
|
continue
|
|
}
|
|
|
|
want, err := def.Resolve(ctx, have)
|
|
if err != nil {
|
|
lines = append(lines, def.Name+": "+err.Error())
|
|
|
|
continue
|
|
}
|
|
|
|
lines = append(lines, gap(def.Name, have, want))
|
|
}
|
|
|
|
return lines
|
|
}
|
|
|
|
func planBuilders(ctx context.Context, r *repo) []string {
|
|
var lines []string
|
|
|
|
tsGo, err := tailscaleGo(ctx)
|
|
if err != nil {
|
|
return []string{"tailscale go directive: " + err.Error()}
|
|
}
|
|
|
|
nixGo, err := goVersion(ctx, r)
|
|
if err != nil {
|
|
return []string{"devShell Go: " + err.Error()}
|
|
}
|
|
|
|
ourMod, err := r.readFile("go.mod")
|
|
if err != nil {
|
|
return []string{err.Error()}
|
|
}
|
|
|
|
ourGo, err := goDirective(ourMod)
|
|
if err != nil {
|
|
return []string{err.Error()}
|
|
}
|
|
|
|
lines = append(lines, fmt.Sprintf("go: go.mod %s, devShell %s, tailscale main %s", ourGo, nixGo, tsGo))
|
|
|
|
for _, set := range []struct {
|
|
pins []goPin
|
|
want string
|
|
}{
|
|
{tailscaleBuilders, tsGo},
|
|
{localBuilders, higher(nixGo, ourGo)},
|
|
} {
|
|
for _, pin := range set.pins {
|
|
content, err := r.readFile(pin.File)
|
|
if err != nil {
|
|
lines = append(lines, err.Error())
|
|
|
|
continue
|
|
}
|
|
|
|
have, ok := currentGolangTag(content)
|
|
if !ok {
|
|
lines = append(lines, pin.File+": no golang builder image found")
|
|
|
|
continue
|
|
}
|
|
|
|
lines = append(lines, gap(pin.File+" golang", have, set.want))
|
|
}
|
|
}
|
|
|
|
return lines
|
|
}
|
|
|
|
func planLockstep(ctx context.Context, r *repo) []string {
|
|
var lines []string
|
|
|
|
for _, pair := range []struct{ owner, dep, target string }{
|
|
{modSqlite, modLibc, ""},
|
|
{modTailscale, modGvisor, "main"},
|
|
} {
|
|
have, err := moduleVersion(ctx, r, pair.owner)
|
|
if err != nil {
|
|
lines = append(lines, pair.owner+": "+err.Error())
|
|
|
|
continue
|
|
}
|
|
|
|
want := have
|
|
|
|
if pair.target == "" {
|
|
if latest, err := latestVersion(ctx, pair.owner, have); err == nil { //nolint:noinlineerr
|
|
want = latest
|
|
}
|
|
}
|
|
|
|
partner, err := partnerVersion(ctx, pair.owner, want, pair.dep)
|
|
if err != nil {
|
|
lines = append(lines, pair.dep+": "+err.Error())
|
|
|
|
continue
|
|
}
|
|
|
|
haveDep, err := moduleVersion(ctx, r, pair.dep)
|
|
if err != nil {
|
|
lines = append(lines, pair.dep+": "+err.Error())
|
|
|
|
continue
|
|
}
|
|
|
|
lines = append(lines, gap(pair.owner, have, want), gap(pair.dep+" (pinned by "+pair.owner+")", haveDep, partner))
|
|
}
|
|
|
|
return lines
|
|
}
|
|
|
|
// gap renders one pin as either current or lagging.
|
|
func gap(what, have, want string) string {
|
|
if have == want {
|
|
return fmt.Sprintf("%s: %s (current)", what, have)
|
|
}
|
|
|
|
return fmt.Sprintf("%s: %s -> %s", what, have, want)
|
|
}
|