Commit 0d422fbdaf
Verified · cmc
Layout: unified · split
cmd/gitbay/ssh.go +22 −21
| @@ -20,39 +20,40 @@ type target struct { | |||
| 20 | repo string // owner/name, "" when not inferable | 20 | repo string // owner/name, "" when not inferable |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | // resolveTarget picks the instance and repo. Inside a git repo whose origin | 23 | // resolveTarget picks the instance and repo. An origin remote matching a |
| 24 | // remote points at a configured (or any ssh) forge host, that wins; | 24 | // CONFIGURED instance wins and carries repo inference; otherwise the |
| 25 | // otherwise the configured default instance. | 25 | // default instance is used with no inference — a clone from some other |
| 26 | // host (github, a different forge) must never hijack the command. The | ||
| 27 | // raw origin serves as an ad-hoc instance only when nothing is configured | ||
| 28 | // at all. | ||
| 26 | func resolveTarget() (target, error) { | 29 | func resolveTarget() (target, error) { |
| 27 | cfg, err := cliconfig.Load() | 30 | cfg, err := cliconfig.Load() |
| 28 | if err != nil { | 31 | if err != nil { |
| 29 | return target{}, err | 32 | return target{}, err |
| 30 | } | 33 | } |
| 31 | 34 | ||
| 32 | if url := originURL(); url != "" { | 35 | parsed, repo, originOK := cliconfig.ParseRemoteURL(originURL()) |
| 33 | if parsed, repo, ok := cliconfig.ParseRemoteURL(url); ok { | 36 | if originOK { |
| 34 | // Prefer a configured instance for the same host+port: it may | 37 | norm := func(p int) int { |
| 35 | // carry ssh_options the bare URL cannot express. | 38 | if p == 0 { |
| 36 | norm := func(p int) int { | 39 | return 22 |
| 37 | if p == 0 { | ||
| 38 | return 22 | ||
| 39 | } | ||
| 40 | return p | ||
| 41 | } | 40 | } |
| 42 | for _, inst := range cfg.Instances { | 41 | return p |
| 43 | if inst.Host == parsed.Host && norm(inst.Port) == norm(parsed.Port) { | 42 | } |
| 44 | return target{inst: inst, repo: repo}, nil | 43 | for _, inst := range cfg.Instances { |
| 45 | } | 44 | if inst.Host == parsed.Host && norm(inst.Port) == norm(parsed.Port) { |
| 45 | return target{inst: inst, repo: repo}, nil | ||
| 46 | } | 46 | } |
| 47 | return target{inst: parsed, repo: repo}, nil | ||
| 48 | } | 47 | } |
| 49 | } | 48 | } |
| 50 | 49 | ||
| 51 | inst, _, err := cfg.DefaultInstance() | 50 | if inst, _, err := cfg.DefaultInstance(); err == nil { |
| 52 | if err != nil { | 51 | return target{inst: inst}, nil |
| 53 | return target{}, err | 52 | } |
| 53 | if originOK { | ||
| 54 | return target{inst: parsed, repo: repo}, nil | ||
| 54 | } | 55 | } |
| 55 | return target{inst: inst}, nil | 56 | return target{}, fmt.Errorf("no gitbay instance configured; run: gitbay remote add <name> <host>") |
| 56 | } | 57 | } |
| 57 | 58 | ||
| 58 | func originURL() string { | 59 | func originURL() string { |
e2e/cli_test.go +16
| @@ -193,6 +193,22 @@ func TestCLI(t *testing.T) { | |||
| 193 | t.Fatalf("init-created repo: %s", out) | 193 | t.Fatalf("init-created repo: %s", out) |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | // A clone whose origin points at a FOREIGN host must not hijack the | ||
| 197 | // command: the configured default instance is used, and repo inference | ||
| 198 | // is dropped rather than guessed across hosts. | ||
| 199 | foreign := filepath.Join(t.TempDir(), "f") | ||
| 200 | os.MkdirAll(foreign, 0o755) | ||
| 201 | mustGit(t, foreign, cliGitEnv, "init", "-q") | ||
| 202 | mustGit(t, foreign, cliGitEnv, "remote", "add", "origin", "git@github.example:someone/thing.git") | ||
| 203 | out = c.must(t, foreign, "", "auth", "whoami") | ||
| 204 | if strings.TrimSpace(out) != "alice" { | ||
| 205 | t.Fatalf("foreign-origin whoami hit the wrong host: %q", out) | ||
| 206 | } | ||
| 207 | _, errOut2, code2 := c.run(t, foreign, "", "issue", "list") | ||
| 208 | if code2 != 2 || !strings.Contains(errOut2, "none inferable") { | ||
| 209 | t.Fatalf("foreign-origin repo inference: exit %d, %s", code2, errOut2) | ||
| 210 | } | ||
| 211 | |||
| 196 | // Man pages and completions generate. | 212 | // Man pages and completions generate. |
| 197 | manDir := t.TempDir() | 213 | manDir := t.TempDir() |
| 198 | c.must(t, "", "", "man", "--dir", manDir) | 214 | c.must(t, "", "", "man", "--dir", manDir) |