Artifact 7d5e42d4344506833abde2609d064fc16daad0428f3cb2089b6101d5eef63efd:
- File
cli/doctor.go
— part of check-in
[38efed7a12]
at
2026-08-12 20:50:57
on branch main
— chore(deps): migrate to go-libfossil v0.9.0 (#195)
* chore(deps): migrate to go-libfossil v0.9.0 (renamed module path)
- import path danmestas/libfossil → danmestas/go-libfossil everywhere - CloneOpts.ProjectCode removed upstream; assert via CloneResult instead - Timeline now takes TimelineOpts (cursor pagination, newest-first) - testutil.HasFossil removed; check FossilBinary() != ""
* ci: retrigger checks
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> (user: [email protected], size: 3327) [annotate] [blame] [check-ins using]
package cli import ( "fmt" "net" "net/url" "os" "os/exec" "path/filepath" "runtime" "strings" "time" libfossilcli "github.com/danmestas/go-libfossil/cli" ) type DoctorCmd struct { NATSUrl string `help:"NATS server URL to check connectivity" default:"nats://localhost:4222"` } func (c *DoctorCmd) Run(g *libfossilcli.Globals) error { passed, warned, failed := 0, 0, 0 check := func(name string, fn func() (string, error)) { detail, err := fn() if err != nil { fmt.Printf(" FAIL %s: %s\n", name, err) failed++ } else if strings.HasPrefix(detail, "WARN:") { fmt.Printf(" WARN %s: %s\n", name, strings.TrimPrefix(detail, "WARN:")) warned++ } else { fmt.Printf(" OK %s: %s\n", name, detail) passed++ } } fmt.Println("=== edgesync doctor ===") fmt.Println() // Go runtime check("go version", func() (string, error) { return runtime.Version(), nil }) // go build works with -buildvcs=false check("go build (buildvcs)", func() (string, error) { cmd := exec.Command("go", "version") out, err := cmd.Output() if err != nil { return "", fmt.Errorf("go not found in PATH") } return strings.TrimSpace(string(out)), nil }) // fossil binary check("fossil binary", func() (string, error) { path, err := exec.LookPath("fossil") if err != nil { return "WARN:" + "not found in PATH (needed for sim/interop tests)", nil } out, _ := exec.Command(path, "version").Output() return strings.TrimSpace(string(out)), nil }) // Repository path check("repository", func() (string, error) { if g.Repo != "" { if _, err := os.Stat(g.Repo); err != nil { return "", fmt.Errorf("%s: %w", g.Repo, err) } return g.Repo, nil } r, err := g.OpenRepo() if err != nil { return "WARN:" + "no .fossil file found in cwd or parents (use -R <path>)", nil } r.Close() return "auto-detected", nil }) // NATS connectivity check("nats connectivity", func() (string, error) { u, err := url.Parse(c.NATSUrl) if err != nil { return "", fmt.Errorf("invalid URL: %s", c.NATSUrl) } host := u.Host if !strings.Contains(host, ":") { host += ":4222" } conn, err := net.DialTimeout("tcp", host, 2*time.Second) if err != nil { return "WARN:" + fmt.Sprintf("%s unreachable (%v)", c.NATSUrl, err), nil } conn.Close() return c.NATSUrl + " reachable", nil }) // Doppler (optional) check("doppler", func() (string, error) { path, err := exec.LookPath("doppler") if err != nil { return "WARN:" + "not found (optional, needed for OTel secret injection)", nil } return path, nil }) // Pre-commit hook check("pre-commit hook", func() (string, error) { hookPath := filepath.Join(".githooks", "pre-commit") if _, err := os.Stat(hookPath); err != nil { return "WARN:" + "not installed (run: make setup-hooks)", nil } // Check if git config points to .githooks out, err := exec.Command("git", "config", "core.hooksPath").Output() if err != nil || strings.TrimSpace(string(out)) != ".githooks" { return "WARN:" + ".githooks exists but git not configured (run: make setup-hooks)", nil } return "installed", nil }) fmt.Println() fmt.Printf("=== %d passed, %d warnings, %d failed ===\n", passed, warned, failed) if failed > 0 { return fmt.Errorf("%d checks failed", failed) } return nil }