26f897c1ec
release / release-please (push) Failing after 1m49s
docs / build (push) Failing after 6m34s
release / build-and-upload (arm64, linux) (push) Has been cancelled
release / build-and-upload (arm64, windows) (push) Has been cancelled
release / build-darwin (amd64, darwin) (push) Has been cancelled
release / checksums (push) Has been cancelled
release / finalize (push) Has been cancelled
release / build-darwin (arm64, darwin) (push) Has been cancelled
release / build-and-upload (amd64, linux) (push) Has been cancelled
release / build-and-upload (amd64, windows) (push) Has been cancelled
docs / deploy (push) Has been cancelled
96 lines
3.7 KiB
Go
96 lines
3.7 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/kunchenguid/no-mistakes/internal/daemon"
|
|
"github.com/kunchenguid/no-mistakes/internal/gate"
|
|
"github.com/kunchenguid/no-mistakes/internal/safeurl"
|
|
"github.com/kunchenguid/no-mistakes/internal/skill"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
const banner = `_ _ ____ _ _ _ ____ ___ ____ _ _ ____ ____
|
|
|\ | | | |\/| | [__ | |__| |_/ |___ [__
|
|
| \| |__| | | | ___] | | | | \_ |___ ___]`
|
|
|
|
func newInitCmd() *cobra.Command {
|
|
var forkURL string
|
|
cmd := &cobra.Command{
|
|
Use: "init",
|
|
Short: "Initialize no-mistakes gate for the current repository",
|
|
Long: "Sets up or refreshes a local bare repo as a gate, installs a post-receive hook,\n" +
|
|
"best-effort isolates the gate hook path from shared local git config writes when Git supports `config --worktree`,\n" +
|
|
"adds or repairs the \"no-mistakes\" git remote, and records the repo in the database.\n\n" +
|
|
"Run this from inside a git repository that has an \"origin\" remote.",
|
|
Args: cobra.NoArgs,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
return trackCommand("init", func() error {
|
|
p, d, err := openResources()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer d.Close()
|
|
|
|
if cmd.Flags().Changed("fork-url") && strings.TrimSpace(forkURL) == "" {
|
|
return fmt.Errorf("init: --fork-url must not be empty")
|
|
}
|
|
repo, created, err := gate.InitWithFork(cmd.Context(), d, p, ".", forkURL)
|
|
if err != nil {
|
|
return fmt.Errorf("init: %w", err)
|
|
}
|
|
if err := daemon.EnsureDaemon(p); err != nil {
|
|
// Only roll back a gate we created in this run; a re-init
|
|
// must never eject a user's pre-existing gate.
|
|
if created {
|
|
if _, ejectErr := gate.Eject(cmd.Context(), d, p, "."); ejectErr != nil {
|
|
return fmt.Errorf("start daemon: %w, rollback init: %v", err, ejectErr)
|
|
}
|
|
}
|
|
return fmt.Errorf("start daemon: %w", err)
|
|
}
|
|
|
|
// Install the agent skill at user level so agents can drive
|
|
// no-mistakes via `/no-mistakes` in any repo. Best-effort: a
|
|
// skill write failure must not undo a successful gate setup.
|
|
_, skillErr := skill.InstallUser()
|
|
|
|
w := cmd.OutOrStdout()
|
|
fmt.Fprintln(w, sCyan.Render(banner))
|
|
fmt.Fprintln(w)
|
|
headline := "Gate initialized"
|
|
if !created {
|
|
headline = "Gate already initialized (refreshed)"
|
|
}
|
|
fmt.Fprintf(w, " %s %s\n", sGreen.Render("✓"), headline)
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintf(w, " %s %s\n", sDim.Render(" repo"), repo.WorkingPath)
|
|
fmt.Fprintf(w, " %s no-mistakes → %s\n", sDim.Render(" gate"), p.RepoDir(repo.ID))
|
|
remoteURL := repo.UpstreamURL
|
|
if repo.ForkURL != "" {
|
|
remoteURL = safeurl.Redact(remoteURL)
|
|
}
|
|
fmt.Fprintf(w, " %s %s\n", sDim.Render("remote"), remoteURL)
|
|
if repo.ForkURL != "" {
|
|
fmt.Fprintf(w, " %s %s\n", sDim.Render(" fork"), safeurl.Redact(repo.ForkURL))
|
|
}
|
|
if skillErr != nil {
|
|
fmt.Fprintf(w, " %s %s\n", sDim.Render(" skill"), sYellow.Render("skipped: "+skillErr.Error()))
|
|
} else {
|
|
fmt.Fprintf(w, " %s %s %s\n", sDim.Render(" skill"), sGreen.Render("/no-mistakes"), sDim.Render("installed for agents at user level"))
|
|
}
|
|
if legacy := skill.Vendored(repo.WorkingPath); len(legacy) > 0 {
|
|
fmt.Fprintf(w, " %s %s\n", sDim.Render(" note"), sDim.Render("vendored skill copy ("+strings.Join(legacy, ", ")+") is no longer needed and can be removed"))
|
|
}
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintf(w, " %s\n", sDim.Render("Push through the gate with:"))
|
|
fmt.Fprintf(w, " %s\n", sBold.Render("git push no-mistakes <branch>"))
|
|
return nil
|
|
})
|
|
},
|
|
}
|
|
cmd.Flags().StringVar(&forkURL, "fork-url", "", "GitHub fork remote URL to push branches to while opening PRs against origin")
|
|
return cmd
|
|
}
|