package client import ( "errors" "fmt" "os" "path/filepath" "strings" "git.nevets.tech/Steven/certman/common" ) // hashFile is the filename inside a domain's local data root that records // the last remote commit SHA the client successfully synced from. The daemon // compares it against the remote HEAD to decide whether a sync is needed. const hashFile = "hash" // defaultBranch is the branch the client tracks on the remote repo. const defaultBranch = "master" // WriteCommitHash persists hash to /hash. Call it after a // successful sync so the next tick can skip a no-op. func WriteCommitHash(certsDir, hash string) error { return os.WriteFile(filepath.Join(certsDir, hashFile), []byte(hash), 0o644) } // LocalCommitHash returns the commit SHA recorded at /hash. A // missing file is not an error: it returns "" so a fresh client falls // through to the full sync path. func LocalCommitHash(certsDir string) (string, error) { data, err := os.ReadFile(filepath.Join(certsDir, hashFile)) if err != nil { if errors.Is(err, os.ErrNotExist) { return "", nil } return "", fmt.Errorf("read hash file: %w", err) } return strings.TrimSpace(string(data)), nil } // RemoteCommitHash returns the current HEAD commit SHA of the domain's repo // on the configured git host. It returns common.ErrRepoNotFound if the repo // does not exist yet, letting the daemon handle the "not provisioned" case // without string-matching errors. func RemoteCommitHash(config *common.AppConfig, domainConfig *common.DomainConfig, domain string) (string, error) { provider, err := common.ProviderFor(config) if err != nil { return "", err } return provider.HeadCommit(domain, defaultBranch, domainConfig) }