Documentation
¶
Index ¶
- func CheckRepoExists(repoName string, existsFn RepoExistsFunc) (bool, error)
- func DeleteStatusError(statusCode int, body string) error
- func EnsureRepoExists(org, repoName string, existsFn RepoExistsFunc) error
- func ReadProtectedTokenFile(path string) (string, error)
- func ResolveToken(configToken, envVar, tokenFileName string) string
- type OwnerType
- type PublicRepo
- type PublicRepoEnsurer
- type PublicRepoLister
- type ReleaseClient
- type ReleasesEnabler
- type RepoClient
- type RepoDescriptionClient
- type RepoExistsFunc
- type UserFallbackPublicRepoLister
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckRepoExists ¶
func CheckRepoExists(repoName string, existsFn RepoExistsFunc) (bool, error)
CheckRepoExists normalizes repo-existence check error handling.
func DeleteStatusError ¶
DeleteStatusError maps common forge delete status codes into stable errors.
func EnsureRepoExists ¶
func EnsureRepoExists(org, repoName string, existsFn RepoExistsFunc) error
EnsureRepoExists validates that a repository exists before destructive actions.
func ReadProtectedTokenFile ¶ added in v0.19.3
ReadProtectedTokenFile reads a credential file at path using hardened semantics shared by every forge client (GitHub, Codeberg, Forgejo, and the CLI's release token loading). Token files live at well-known paths under the user's home directory, so a local attacker able to plant something at that path before gitsyncer runs could otherwise cause it to:
- follow a symlink and read an unrelated, possibly sensitive file, or
- open a FIFO and block the process indefinitely, or
- read a token file that is also readable by other local users/groups, leaking the credential.
openProtectedTokenFile (platform-specific) opens the path with O_NOFOLLOW|O_NONBLOCK so a symlink is rejected outright and a FIFO cannot block the open call. The Stat check below then rejects anything that isn't a plain regular file and any file with group/other permission bits set (mode&0077 != 0), i.e. it only accepts owner-only files such as 0600 or 0400. The returned token has leading/trailing whitespace trimmed, since tokens are commonly stored with a trailing newline.
func ResolveToken ¶ added in v0.19.3
ResolveToken resolves a forge API token via the shared config -> env var -> token file cascade. This is the single source of truth for token precedence: it used to be reimplemented separately by the GitHub client's loadToken, the Codeberg client's loadToken and loadForgejoToken, and the CLI release pipeline's loadTokenWithFallback, with subtly different trimming behavior between the copies (task g01 consolidated them here, building on the shared ReadProtectedTokenFile extracted for task 901).
Precedence, matching every caller's prior behavior:
- configToken, if non-empty (e.g. a value from gitsyncer's config file).
- The environment variable named envVar, if set and non-empty.
- A protected token file named tokenFileName under the user's home directory, read via ReadProtectedTokenFile.
configToken and the environment variable are both trimmed here for consistency with the token file (ReadProtectedTokenFile already trims its result), since tokens are commonly copy-pasted or piped from a secret store with a trailing newline.
Returns "" if none of the three sources yield a non-empty token, including when the home directory cannot be determined or the token file cannot be read (missing, wrong permissions, etc.) - callers treat "" as "no token configured" rather than a hard error, exactly as before consolidation.
Types ¶
type OwnerType ¶ added in v0.19.3
type OwnerType string
OwnerType identifies whether a repository owner is a user or organization.
type PublicRepo ¶ added in v0.19.3
PublicRepo is a forge-agnostic view of a repository returned by a public repository listing. github.Client and codeberg.Client each list repositories as their own concrete Repository DTO (with many forge-specific fields); callers that only need name/description convert into this shared type via a thin adapter (see internal/cli's githubPublicRepoLister/codebergPublicRepoLister), so public-sync code depends on this package instead of importing github/codeberg for their concrete types.
type PublicRepoEnsurer ¶ added in v0.19.3
PublicRepoEnsurer is implemented by forge clients that can idempotently ensure a public repository exists: create it if absent, or validate that an existing repository is a compatible (public, same-name) target. internal/sync depends on this narrow interface instead of importing a concrete forge package (e.g. codeberg) directly, so the backup-repo bootstrapping in ensureForgejoBackups stays decoupled from any single forge implementation. codeberg.Client implements this method.
type PublicRepoLister ¶ added in v0.19.3
type PublicRepoLister interface {
HasToken() bool
ListPublicRepos() ([]PublicRepo, error)
}
PublicRepoLister lists public repositories for a forge account. HasToken is part of the contract because GitHub's public-listing API requires an auth token even for public repositories, unlike Codeberg's; callers check it before calling ListPublicRepos.
type ReleaseClient ¶ added in v0.19.3
type ReleaseClient interface {
// GetReleases returns the tag names of existing releases for the
// repository. A missing repository is reported as an empty slice and a
// nil error so callers can treat it as "no releases yet".
GetReleases(owner, repo string) ([]string, error)
CreateRelease(owner, repo, tag, releaseNotes string) error
UpdateRelease(owner, repo, tag, releaseNotes string) error
}
ReleaseClient defines release CRUD operations shared across forges. Each forge (GitHub, Codeberg/Gitea) implements this against its own API so the release pipeline can talk to any forge through a single abstraction instead of hand-rolled per-forge HTTP in the caller.
type ReleasesEnabler ¶ added in v0.19.3
ReleasesEnabler is optionally implemented by forges that require releases to be enabled per-repository before release creation can succeed (e.g. Codeberg/Gitea, where the repository's Releases feature may be disabled). Callers check for this interface rather than assuming every forge needs it.
type RepoClient ¶
type RepoClient interface {
HasToken() bool
RepoExists(repoName string) (bool, error)
CreateRepo(repoName, description string, private bool) error
DeleteRepo(repoName string) error
}
RepoClient defines shared repository lifecycle operations across forges.
type RepoDescriptionClient ¶
type RepoDescriptionClient interface {
RepoClient
GetRepoDescription(repoName string) (string, bool, error)
UpdateRepoDescription(repoName, description string) error
}
RepoDescriptionClient defines shared description operations across forges.
type RepoExistsFunc ¶
RepoExistsFunc checks if a repository exists.
type UserFallbackPublicRepoLister ¶ added in v0.19.3
type UserFallbackPublicRepoLister interface {
ListPublicRepos() ([]PublicRepo, error)
ListUserPublicRepos() ([]PublicRepo, error)
}
UserFallbackPublicRepoLister is implemented by forges (Codeberg/Gitea) whose public-repo listing must retry as a user-scoped listing when the organization-scoped listing fails, e.g. because the configured account is a user rather than an organization. Unlike PublicRepoLister it has no HasToken method because Codeberg's public listing does not require a token.