From 6148be40dad7c30b6eebbbd5e4864593b2c89b3e Mon Sep 17 00:00:00 2001 From: wbtiger <28288271@qq.com> Date: Tue, 14 Jul 2026 22:03:17 +0800 Subject: [PATCH] fix(api): restore resolveAPIPath after MSYS2 merge conflict resolution The merge of PR #406 (MSYS2 path fix) via --theirs accidentally dropped the resolveAPIPath function added by PR #254. This commit restores the :owner/:repo placeholder and --var template resolution while keeping the MSYS2 path restoration as the first step. --- cmd/api/api.go | 52 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/cmd/api/api.go b/cmd/api/api.go index 02dc164..bb41861 100644 --- a/cmd/api/api.go +++ b/cmd/api/api.go @@ -14,10 +14,18 @@ import ( "github.com/gitlink-org/gitlink-cli/cmd/cmdutil" "github.com/gitlink-org/gitlink-cli/internal/client" + "github.com/gitlink-org/gitlink-cli/internal/context" "github.com/gitlink-org/gitlink-cli/internal/i18n" "github.com/gitlink-org/gitlink-cli/internal/output" ) +// apiOwnerPlaceholder and apiRepoPlaceholder match the REST-style :owner / :repo +// path placeholders used throughout the GitLink API docs and shortcut commands. +var ( + apiOwnerPlaceholder = regexp.MustCompile(`:owner\b`) + apiRepoPlaceholder = regexp.MustCompile(`:repo\b`) +) + func NewAPICmd(translators ...*i18n.Translator) *cobra.Command { tr := i18n.Default() if len(translators) > 0 && translators[0] != nil { @@ -94,14 +102,14 @@ func runAPI(c *cobra.Command, args []string) error { } method := strings.ToUpper(args[0]) - path := args[1] - // Fix MSYS2/Git Bash path auto-conversion on Windows: + // Fix MSYS2/Git Bash path auto-conversion on Windows first: // "/v1/owner/repo" is rewritten to "C:/Program Files/Git/v1/owner/repo". - path = restoreAPIPath(path) + rawPath := restoreAPIPath(args[1]) - if !strings.HasPrefix(path, "/") { - path = "/" + path + path, err := resolveAPIPath(c, rawPath) + if err != nil { + return err } cli, err := client.New() @@ -138,6 +146,40 @@ func runAPI(c *cobra.Command, args []string) error { return output.Print(env, resolveFormat()) } +// resolveAPIPath prepares a single-call path: it renders {{var}} templates +// supplied via --var (consistent with batch mode), substitutes the REST-style +// :owner / :repo placeholders (resolved from --owner/--repo or the git remote, +// exactly like the shortcut commands), and ensures a leading slash. +func resolveAPIPath(c *cobra.Command, rawPath string) (string, error) { + path := rawPath + + overrides, err := parseBatchVars(c) + if err != nil { + return "", err + } + if len(overrides) > 0 { + rendered, rerr := renderTemplate(path, overrides) + if rerr != nil { + return "", rerr + } + path = rendered + } + + if apiOwnerPlaceholder.MatchString(path) || apiRepoPlaceholder.MatchString(path) { + owner, repo, rerr := context.ResolveOwnerRepo(cmdutil.Owner, cmdutil.Repo) + if rerr != nil { + return "", fmt.Errorf("path contains :owner/:repo placeholders but they could not be resolved: %w", rerr) + } + path = apiOwnerPlaceholder.ReplaceAllLiteralString(path, owner) + path = apiRepoPlaceholder.ReplaceAllLiteralString(path, repo) + } + + if !strings.HasPrefix(path, "/") { + path = "/" + path + } + return path, nil +} + func readJSONBody(c *cobra.Command) (interface{}, error) { bodyStr, _ := c.Flags().GetString("body") bodyFile, _ := c.Flags().GetString("body-file")