nomadcode/services/core/internal/projectsync/checkout.go
toki 0d6916fd48 feat: project sync checkout implementation and task archive migration
- Add projectsync package with checkout logic and tests
- Integrate project sync into server initialization
- Update HTTP handlers and middleware for project sync endpoints
- Update workitempipeline service with project sync support
- Migrate task documents to archive structure with standardized naming
2026-06-07 03:29:53 +09:00

49 lines
2 KiB
Go

package projectsync
// CheckoutPlan is the policy object describing where a single workspace slot
// should be checked out for a project sync target. It is derived purely from a
// normalized Config and a reserved WorkspaceSlot; building it never runs a git
// process. Actual clone/fetch/checkout execution is out of this package's scope.
type CheckoutPlan struct {
// RemoteURL and SourceBranch always come from the project sync Config, never
// from request input, so every slot of the same project checks out the same
// remote and source-of-truth branch.
RemoteURL string
SourceBranch string
// ProjectWorkspaceRoot is the per-project workspace root and SlotPath is this
// slot's independent checkout directory under that root.
ProjectWorkspaceRoot string
SlotPath string
SlotIndex SlotIndex
}
// BuildCheckoutPlan derives a CheckoutPlan from a project sync Config and a
// reserved slot. The git remote and source branch are read from the Config so
// they can never be spoofed by request input, and each slot resolves to its own
// zero-padded checkout path (000 for the default single-operation slot, 001/002
// for parallel slots). It returns ErrInvalidConfig when the Config or slot index
// is invalid.
func BuildCheckoutPlan(config Config, slot WorkspaceSlot) (CheckoutPlan, error) {
normalized, err := config.Normalize()
if err != nil {
return CheckoutPlan{}, err
}
if !slot.Index.Valid() {
return CheckoutPlan{}, ErrInvalidConfig
}
root, err := ProjectWorkspaceRoot(normalized.WorkspaceBasePath, normalized.RepoDirName)
if err != nil {
return CheckoutPlan{}, err
}
slotPath, err := SlotWorkspacePath(normalized.WorkspaceBasePath, normalized.RepoDirName, slot.Index)
if err != nil {
return CheckoutPlan{}, err
}
return CheckoutPlan{
RemoteURL: normalized.GitRemoteURL,
SourceBranch: normalized.SourceBranch,
ProjectWorkspaceRoot: root,
SlotPath: slotPath,
SlotIndex: slot.Index,
}, nil
}