package github import ( "context" "fmt" "os" "strings" "github.com/google/go-github/v55/github" "golang.org/x/oauth2" ) // Client wraps the GitHub API client type Client struct { client *github.Client ctx context.Context } // NewClient creates a new GitHub client func NewClient(token string) (*Client, error) { ctx := context.Background() var client *github.Client if token != "" { ts := oauth2.StaticTokenSource( &oauth2.Token{AccessToken: token}, ) tc := oauth2.NewClient(ctx, ts) client = github.NewClient(tc) } else { client = github.NewClient(nil) } return &Client{ client: client, ctx: ctx, }, nil } // Repository represents a GitHub repository type Repository struct { Owner string Name string URL string CloneURL string DefaultBranch string } // ParseRepoURL extracts owner and name from GitHub URL func ParseRepoURL(url string) (*Repository, error) { // Expected format: https://github.com/owner/repo parts := strings.Split(url, "/") if len(parts) < 5 { return nil, fmt.Errorf("invalid GitHub URL") } owner := parts[len(parts)-2] name := parts[len(parts)-1] // Remove .git suffix if present name = strings.TrimSuffix(name, ".git") return &Repository{ Owner: owner, Name: name, URL: url, CloneURL: fmt.Sprintf("https://github.com/%s/%s.git", owner, name), }, nil } // GetRepositoryInfo fetches repository metadata from GitHub func (c *Client) GetRepositoryInfo(url string) (*Repository, error) { repo, err := ParseRepoURL(url) if err != nil { return nil, err } ghRepo, _, err := c.client.Repositories.Get(c.ctx, repo.Owner, repo.Name) if err != nil { return nil, err } repo.DefaultBranch = ghRepo.GetDefaultBranch() if repo.DefaultBranch == "" { repo.DefaultBranch = "main" } return repo, nil } // CloneRepository clones a repository to a temporary directory func (c *Client) CloneRepository(url string, token string) (string, error) { repo, err := ParseRepoURL(url) if err != nil { return "", err } // Create temp directory tmpDir, err := os.MkdirTemp("", "repo-diagram-*") if err != nil { return "", err } // Build clone URL with token if provided cloneURL := repo.CloneURL if token != "" { cloneURL = fmt.Sprintf("https://x-access-token:%s@github.com/%s/%s.git", token, repo.Owner, repo.Name) } // Clone using git command (simpler than go-git for now) cmd := fmt.Sprintf("git clone --depth 1 --branch %s %s %s", repo.DefaultBranch, cloneURL, tmpDir) if err := runCommand(cmd); err != nil { os.RemoveAll(tmpDir) return "", err } return tmpDir, nil } // GetLanguages returns the language breakdown of a repository func (c *Client) GetLanguages(url string) (map[string]int, error) { repo, err := ParseRepoURL(url) if err != nil { return nil, err } languages, _, err := c.client.Repositories.ListLanguages(c.ctx, repo.Owner, repo.Name) if err != nil { return nil, err } return languages, nil } // runCommand executes a shell command func runCommand(cmd string) error { return nil // Implement with exec.Command }