diff options
| author | Paul Buetow <paul@buetow.org> | 2025-06-24 10:00:28 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2025-06-24 10:00:28 +0300 |
| commit | af8ab19f5def6f00081b0a6d1e5b20b76683f720 (patch) | |
| tree | 89ab045f8da4af0bb6af8b26e7851e7bddfad6e7 /doc/api-reference.md | |
| parent | 577d3d37a47dc7279d7e56975448aa330d6b5469 (diff) | |
refactor: use value semantics for GitHub and Codeberg clients
- Changed github.NewClient() to return Client instead of *Client
- Changed codeberg.NewClient() to return Client instead of *Client
- Updated sync_handlers.go to handle value semantics properly
- Both clients only contain immutable string fields, making value semantics more appropriate
docs: add comprehensive documentation
- Added doc/ directory with full documentation
- Created architecture overview explaining system design
- Added complete API reference for all packages, types, and functions
- Created configuration guide with examples
- Added usage examples and common workflows
- Created development guide for contributors
- Updated README with links to documentation
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'doc/api-reference.md')
| -rw-r--r-- | doc/api-reference.md | 514 |
1 files changed, 514 insertions, 0 deletions
diff --git a/doc/api-reference.md b/doc/api-reference.md new file mode 100644 index 0000000..cc4f69c --- /dev/null +++ b/doc/api-reference.md @@ -0,0 +1,514 @@ +# GitSyncer API Reference + +This document provides a complete reference for all packages, types, and functions in GitSyncer. + +## Table of Contents + +- [Package main](#package-main) +- [Package cli](#package-cli) +- [Package codeberg](#package-codeberg) +- [Package config](#package-config) +- [Package github](#package-github) +- [Package sync](#package-sync) +- [Package version](#package-version) + +--- + +## Package main + +**Location**: `cmd/gitsyncer/main.go` + +The main package provides the application entry point. + +### Functions + +#### func main() +Application entry point that: +- Parses command-line flags +- Routes to appropriate handlers +- Manages exit codes + +--- + +## Package cli + +**Location**: `internal/cli/` + +The cli package handles all command-line interface operations. + +### Types + +#### type Flags +```go +type Flags struct { + VersionFlag bool // Show version information + ConfigPath string // Path to configuration file + ListOrgs bool // List configured organizations + ListRepos bool // List configured repositories + SyncRepo string // Single repository to sync + SyncAll bool // Sync all configured repositories + SyncCodebergPublic bool // Sync all public Codeberg repos + SyncGitHubPublic bool // Sync all public GitHub repos + FullSync bool // Full bidirectional sync + CreateGitHubRepos bool // Auto-create GitHub repositories + CreateCodebergRepos bool // Auto-create Codeberg repositories + DryRun bool // Preview mode without changes + WorkDir string // Working directory for operations + TestGitHubToken bool // Test GitHub authentication +} +``` + +### Functions + +#### func ParseFlags() *Flags +Parses command-line arguments and returns a Flags struct with all options. + +#### func HandleVersion() int +Displays version information and returns exit code 0. + +#### func HandleTestGitHubToken() int +Tests GitHub token authentication: +- Loads token from config/env/file +- Validates token with API call +- Returns 0 on success, 1 on failure + +#### func LoadConfig(configPath string) (*config.Config, error) +Loads configuration from specified path or default locations: +- `./gitsyncer.json` +- `~/.config/gitsyncer/config.json` +- `~/.gitsyncer.json` + +#### func ShowConfigHelp() +Displays help for creating configuration files with example. + +#### func HandleListOrgs(cfg *config.Config) int +Lists all configured organizations from config. + +#### func HandleListRepos(cfg *config.Config) int +Lists all configured repositories from config. + +#### func ShowUsage(cfg *config.Config) +Displays comprehensive usage information. + +#### func HandleSync(cfg *config.Config, flags *Flags) int +Synchronizes a single repository specified by `--sync` flag. + +#### func HandleSyncAll(cfg *config.Config, flags *Flags) int +Synchronizes all repositories listed in configuration. + +#### func HandleSyncCodebergPublic(cfg *config.Config, flags *Flags) int +Discovers and syncs all public Codeberg repositories to other platforms. + +#### func HandleSyncGitHubPublic(cfg *config.Config, flags *Flags) int +Discovers and syncs all public GitHub repositories to other platforms. + +#### func ShowFullSyncMessage() +Displays information about full sync mode. + +### Helper Functions (sync_handlers.go) + +#### func createGitHubRepoIfNeeded(cfg *config.Config, repoName string) error +Creates GitHub repository if it doesn't exist and token is available. + +#### func initGitHubClient(cfg *config.Config) *github.Client +Initializes GitHub client with token from configuration. + +#### func createRepoWithClient(client *github.Client, repoName, description string) error +Creates repository using provided GitHub client. + +#### func showReposToSync(repoNames []string) +Displays list of repositories that will be synced. + +#### func syncCodebergRepos(cfg *config.Config, flags *Flags, repos []codeberg.Repository, repoNames []string) int +Synchronizes discovered Codeberg repositories. + +#### func syncGitHubRepos(cfg *config.Config, flags *Flags, repos []github.Repository, repoNames []string) int +Synchronizes discovered GitHub repositories. + +--- + +## Package codeberg + +**Location**: `internal/codeberg/codeberg.go` + +The codeberg package provides a client for interacting with Codeberg's Gitea API. + +### Types + +#### type Repository +```go +type Repository struct { + ID int64 `json:"id"` // Repository ID + Name string `json:"name"` // Repository name + FullName string `json:"full_name"` // Full name (org/repo) + Description string `json:"description"` // Repository description + Private bool `json:"private"` // Is private repository + Fork bool `json:"fork"` // Is fork + CreatedAt time.Time `json:"created_at"` // Creation timestamp + UpdatedAt time.Time `json:"updated_at"` // Last update timestamp + CloneURL string `json:"clone_url"` // HTTPS clone URL + SSHURL string `json:"ssh_url"` // SSH clone URL + Size int `json:"size"` // Repository size + Archived bool `json:"archived"` // Is archived + Empty bool `json:"empty"` // Is empty repository +} +``` + +#### type Client +```go +type Client struct { + baseURL string // API base URL (https://codeberg.org/api/v1) + org string // Organization or username +} +``` + +### Functions + +#### func NewClient(org string) Client +Creates a new Codeberg API client for the specified organization/user. + +### Methods + +#### func (c *Client) ListPublicRepos() ([]Repository, error) +Lists all public repositories for an organization: +- Handles pagination automatically +- Filters out private, fork, archived, and empty repos +- Returns error on API failure + +#### func (c *Client) ListUserPublicRepos() ([]Repository, error) +Lists all public repositories for a user: +- Same filtering as ListPublicRepos +- Use when org endpoint fails (for user accounts) + +#### func GetRepoNames(repos []Repository) []string +Extracts repository names from a slice of Repository structs. + +--- + +## Package config + +**Location**: `internal/config/config.go` + +The config package handles configuration loading and validation. + +### Types + +#### type Organization +```go +type Organization struct { + Host string `json:"host"` // Git host (e.g., "git@github.com") + Name string `json:"name"` // Organization/username + GitHubToken string `json:"github_token"` // Optional GitHub API token +} +``` + +#### type Config +```go +type Config struct { + Organizations []Organization `json:"organizations"` // List of git organizations + Repositories []string `json:"repositories"` // Specific repos to sync + ExcludeBranches []string `json:"exclude_branches"` // Regex patterns for branch exclusion +} +``` + +### Functions + +#### func Load(path string) (*Config, error) +Loads configuration from JSON file: +- Validates JSON structure +- Calls Validate() on loaded config +- Returns error on failure + +### Methods + +#### func (c *Config) Validate() error +Validates configuration: +- Ensures at least one organization exists +- Returns error if validation fails + +#### func (o *Organization) GetGitURL() string +Returns the Git URL for the organization in format `host:name`. + +#### func (c *Config) FindOrganization(host string) *Organization +Finds organization by host string. + +#### func (o *Organization) IsCodeberg() bool +Returns true if organization host contains "codeberg.org". + +#### func (c *Config) FindCodebergOrg() *Organization +Finds first Codeberg organization in config. + +#### func (o *Organization) IsGitHub() bool +Returns true if organization host contains "github.com". + +#### func (c *Config) FindGitHubOrg() *Organization +Finds first GitHub organization in config. + +--- + +## Package github + +**Location**: `internal/github/github.go` + +The github package provides a client for GitHub API operations. + +### Types + +#### type Client +```go +type Client struct { + token string // GitHub personal access token + org string // Organization or username +} +``` + +#### type Repository +```go +type Repository struct { + Name string `json:"name"` // Repository name + Description string `json:"description"` // Repository description + Private bool `json:"private"` // Is private repository + Fork bool `json:"fork"` // Is fork + Archived bool `json:"archived"` // Is archived + Disabled bool `json:"disabled"` // Is disabled + Size int `json:"size"` // Repository size in KB +} +``` + +#### type CreateRepoRequest +```go +type CreateRepoRequest struct { + Name string `json:"name"` // Repository name + Description string `json:"description"` // Repository description + Private bool `json:"private"` // Create as private + AutoInit bool `json:"auto_init"` // Initialize with README +} +``` + +#### type CreateRepoResponse +```go +type CreateRepoResponse struct { + ID int64 `json:"id"` // Repository ID + Name string `json:"name"` // Repository name + FullName string `json:"full_name"` // Full name (owner/repo) + Private bool `json:"private"` // Is private + SSHURL string `json:"ssh_url"` // SSH clone URL + CloneURL string `json:"clone_url"` // HTTPS clone URL +} +``` + +#### type ErrorResponse +```go +type ErrorResponse struct { + Message string `json:"message"` // Error message + Errors []struct { + Resource string `json:"resource"` // Resource type + Field string `json:"field"` // Field with error + Code string `json:"code"` // Error code + } `json:"errors,omitempty"` +} +``` + +### Functions + +#### func NewClient(token, org string) Client +Creates new GitHub API client: +- If token is empty, tries GITHUB_TOKEN env var +- If still empty, tries ~/.gitsyncer_github_token file +- Returns client with loaded token + +### Methods + +#### func (c *Client) HasToken() bool +Returns true if client has a token configured. + +#### func (c *Client) RepoExists(repoName string) (bool, error) +Checks if repository exists: +- Returns (true, nil) if exists +- Returns (false, nil) if not found (404) +- Returns (false, error) for other errors + +#### func (c *Client) CreateRepo(repoName, description string, private bool) error +Creates a new repository: +- Checks if repo already exists first +- Creates with provided settings +- Returns nil if already exists or created successfully + +#### func (c *Client) ListPublicRepos() ([]Repository, error) +Lists all public repositories: +- Handles pagination automatically +- Filters out private, fork, archived, disabled, and empty repos +- Requires authentication token + +#### func GetRepoNames(repos []Repository) []string +Extracts repository names from Repository slice. + +--- + +## Package sync + +**Location**: `internal/sync/` + +The sync package contains the core synchronization logic. + +### Types + +#### type Syncer +```go +type Syncer struct { + config *config.Config // Configuration + workDir string // Working directory + repoName string // Current repository name + abandonedReports map[string]*AbandonedBranchReport // Abandoned branch reports + branchFilter *BranchFilter // Branch exclusion filter +} +``` + +#### type BranchInfo +```go +type BranchInfo struct { + Name string // Branch name + LastCommit time.Time // Last commit timestamp + Remote string // Remote name + IsAbandoned bool // Whether branch is abandoned + AbandonReason string // Reason for abandonment +} +``` + +#### type AbandonedBranchReport +```go +type AbandonedBranchReport struct { + MainBranchUpdated bool // Is main branch active + MainBranchLastCommit time.Time // Main branch last commit + AbandonedBranches []BranchInfo // List of abandoned branches + TotalBranches int // Total number of branches +} +``` + +#### type BranchFilter +```go +type BranchFilter struct { + excludePatterns []*regexp.Regexp // Compiled regex patterns +} +``` + +### Functions + +#### func New(cfg *config.Config, workDir string) *Syncer +Creates new Syncer instance with configuration and working directory. + +### Syncer Methods + +#### func (s *Syncer) SyncRepository(repoName string) error +Main synchronization method: +1. Creates work directory +2. Sets up repository (clone or configure remotes) +3. Fetches from all remotes +4. Gets and filters branches +5. Syncs each branch +6. Analyzes abandoned branches +7. Returns error on failure + +#### func (s *Syncer) GenerateAbandonedBranchSummary() string +Generates summary report of abandoned branches across all synced repositories. + +### Branch Filter Functions + +#### func NewBranchFilter(excludePatterns []string) (*BranchFilter, error) +Creates new branch filter with compiled regex patterns. + +### BranchFilter Methods + +#### func (f *BranchFilter) ShouldExclude(branchName string) bool +Returns true if branch matches any exclusion pattern. + +#### func (f *BranchFilter) FilterBranches(branches []string) []string +Returns branches that don't match exclusion patterns. + +#### func (f *BranchFilter) GetExcludedBranches(branches []string) []string +Returns branches that match exclusion patterns. + +#### func FormatExclusionReport(excludedBranches []string, patterns []string) string +Formats a report of excluded branches with patterns used. + +### Git Operation Functions (git_operations.go) + +#### func checkForMergeConflicts() (bool, string, error) +Checks if repository has merge conflicts. + +#### func stashChanges() error +Stashes uncommitted changes. + +#### func popStash() +Pops the last stash (called via defer). + +#### func getRemotesList() (map[string]bool, error) +Returns map of configured remotes. + +#### func getAllUniqueBranches(gitOutput []byte) []string +Parses git branch output and returns unique branch names. + +#### func changeToRepoDirectory(repoPath string) (func(), error) +Changes to repository directory and returns restore function. + +#### func fetchRemote(remote string) error +Fetches from a specific remote with prune. + +#### func checkoutExistingBranch(branch string) error +Checks out an existing local branch. + +#### func createTrackingBranch(branch, remoteName string) error +Creates new branch tracking a remote branch. + +#### func mergeFromRemotes(branch string, remotesWithBranch map[string]bool) error +Merges changes from all remotes that have the branch. + +#### func pushToAllRemotes(branch string, remotes map[string]*config.Organization, remotesWithBranch map[string]bool) error +Pushes branch to all configured remotes. + +### Internal Helper Functions + +#### func (s *Syncer) setupRepository(repoPath string) error +Sets up repository by cloning or adding remotes. + +#### func (s *Syncer) analyzeAbandonedBranches() (*AbandonedBranchReport, error) +Analyzes branches for abandonment (6+ months inactive). + +#### func (s *Syncer) findMainBranch(branches []string) string +Finds the main branch (main, master, or develop). + +#### func (s *Syncer) trackRemotesWithBranch(branch string, remotes map[string]*config.Organization) map[string]bool +Returns map of remotes that have the specified branch. + +--- + +## Package version + +**Location**: `internal/version/version.go` + +The version package provides version information. + +### Variables + +```go +var ( + Version = "0.1.0" // Application version + GitCommit = "unknown" // Git commit hash (set at build time) + BuildDate = "unknown" // Build date (set at build time) + GoVersion = runtime.Version() // Go version used for build +) +``` + +### Functions + +#### func GetVersion() string +Returns full version string with all metadata: +``` +gitsyncer version 0.1.0 + Git commit: abc123 + Built: 2024-01-15 + Go version: go1.21.5 +``` + +#### func GetShortVersion() string +Returns just the version number: `0.1.0`
\ No newline at end of file |
