|
| 1 | +// Package fetch provides convenience functions for fetching pull requests |
| 2 | +// with automatic platform detection and authentication resolution. |
| 3 | +package fetch |
| 4 | + |
| 5 | +import ( |
| 6 | + "context" |
| 7 | + "fmt" |
| 8 | + "log/slog" |
| 9 | + |
| 10 | + "github.com/codeGROOVE-dev/prx/pkg/prx" |
| 11 | + "github.com/codeGROOVE-dev/prx/pkg/prx/auth" |
| 12 | + "github.com/codeGROOVE-dev/prx/pkg/prx/gitea" |
| 13 | + "github.com/codeGROOVE-dev/prx/pkg/prx/github" |
| 14 | + "github.com/codeGROOVE-dev/prx/pkg/prx/gitlab" |
| 15 | +) |
| 16 | + |
| 17 | +// Fetch automatically detects the platform from a PR/MR URL, resolves authentication, |
| 18 | +// and fetches the pull request data. This is the simplest way to use prx. |
| 19 | +// |
| 20 | +// Example: |
| 21 | +// |
| 22 | +// data, err := fetch.Fetch(ctx, "https://github.com/owner/repo/pull/123") |
| 23 | +// data, err := fetch.Fetch(ctx, "https://gitlab.com/owner/repo/-/merge_requests/456") |
| 24 | +// data, err := fetch.Fetch(ctx, "https://codeberg.org/owner/repo/pulls/789") |
| 25 | +// data, err := fetch.Fetch(ctx, "https://gitea.example.com/owner/repo/pulls/100") |
| 26 | +// |
| 27 | +// The function will: |
| 28 | +// - Parse the URL to detect platform, owner, repo, and PR number |
| 29 | +// - Automatically resolve authentication tokens from environment variables or CLI tools |
| 30 | +// - Create the appropriate platform client |
| 31 | +// - Fetch and return the pull request data |
| 32 | +// |
| 33 | +// Authentication is resolved in this order: |
| 34 | +// - GitHub: GITHUB_TOKEN, GH_TOKEN env vars, or 'gh auth token' |
| 35 | +// - GitLab: GITLAB_TOKEN, GL_TOKEN env vars, or 'glab config get token' |
| 36 | +// - Gitea/Codeberg: CODEBERG_TOKEN, GITEA_TOKEN env vars, tea config, or 'berg auth token' |
| 37 | +// |
| 38 | +// URL fragments (#...) and query parameters (?...) are automatically stripped. |
| 39 | +// Unknown hosts default to Gitea unless the URL indicates GitHub or GitLab. |
| 40 | +// |
| 41 | +// Use WithOptions to pass additional client configuration options. |
| 42 | +func Fetch(ctx context.Context, url string, opts ...prx.Option) (*prx.PullRequestData, error) { |
| 43 | + // Parse URL to get platform, owner, repo, PR number |
| 44 | + parsed, err := prx.ParseURL(url) |
| 45 | + if err != nil { |
| 46 | + return nil, fmt.Errorf("parsing URL: %w", err) |
| 47 | + } |
| 48 | + |
| 49 | + // Resolve authentication token for the platform |
| 50 | + resolver := auth.NewResolver() |
| 51 | + authPlatform := auth.DetectPlatform(parsed.Platform) |
| 52 | + token, err := resolver.Resolve(ctx, authPlatform, parsed.Host) |
| 53 | + if err != nil { |
| 54 | + return nil, fmt.Errorf("resolving authentication for %s: %w", parsed.Platform, err) |
| 55 | + } |
| 56 | + |
| 57 | + // Create platform-specific client |
| 58 | + var platform prx.Platform |
| 59 | + switch parsed.Platform { |
| 60 | + case prx.PlatformGitHub: |
| 61 | + platform = github.NewPlatform(token.Value) |
| 62 | + case prx.PlatformGitLab: |
| 63 | + platform = gitlab.NewPlatform(token.Value, gitlab.WithBaseURL("https://"+parsed.Host)) |
| 64 | + case prx.PlatformCodeberg: |
| 65 | + platform = gitea.NewCodebergPlatform(token.Value) |
| 66 | + default: |
| 67 | + // Default to Gitea for unknown platforms |
| 68 | + platform = gitea.NewPlatform(token.Value, gitea.WithBaseURL("https://"+parsed.Host)) |
| 69 | + } |
| 70 | + |
| 71 | + // Create client and fetch PR |
| 72 | + client := prx.NewClientWithPlatform(platform, opts...) |
| 73 | + defer func() { |
| 74 | + if closeErr := client.Close(); closeErr != nil { |
| 75 | + slog.WarnContext(ctx, "failed to close client", "error", closeErr) |
| 76 | + } |
| 77 | + }() |
| 78 | + |
| 79 | + return client.PullRequest(ctx, parsed.Owner, parsed.Repo, parsed.Number) |
| 80 | +} |
| 81 | + |
| 82 | +// WithOptions is an alias for Fetch for backwards compatibility. |
| 83 | +// |
| 84 | +// Deprecated: Use Fetch directly, which now accepts options. |
| 85 | +func WithOptions(ctx context.Context, url string, opts ...prx.Option) (*prx.PullRequestData, error) { |
| 86 | + return Fetch(ctx, url, opts...) |
| 87 | +} |
0 commit comments