nomadcode/services/core/internal/projectsync/checkout.go
toki f9c6be03ef feat: milestone work-item creation sync 관련 변경사항 커밋
- projectsync: checkout, config 모듈 개선 및 테스트 추가
- workitempipeline: service 개선 및 테스트 추가
- http handlers 테스트 업데이트
- client: proto_socket_branch_event_service.dart 추가 및 테스트
- contracts notes 업데이트
- agent-task: milestone 하위 subtask PLAN/CODE_REVIEW 문서 추가
2026-06-13 16:45:10 +09:00

90 lines
3.4 KiB
Go

package projectsync
// ProvisionPlan describes the complete workspace topology that must be prepared
// for a project before any slot checkout or sync operation can run. Building it
// never executes a git process; it only resolves paths from a normalized Config.
type ProvisionPlan struct {
ProjectWorkspaceRoot string
MainBranchPath string
DevelopBranchPath string
DefaultSlotPath string
}
// BuildProvisionPlan derives the workspace topology plan from a project sync
// Config. It returns ErrInvalidConfig when the Config cannot be normalized.
func BuildProvisionPlan(config Config) (ProvisionPlan, error) {
normalized, err := config.Normalize()
if err != nil {
return ProvisionPlan{}, err
}
root, err := ProjectWorkspaceRoot(normalized.WorkspaceBasePath, normalized.RepoDirName)
if err != nil {
return ProvisionPlan{}, err
}
mainPath, err := BranchWorkspacePath(normalized.WorkspaceBasePath, normalized.RepoDirName, BranchNameMain)
if err != nil {
return ProvisionPlan{}, err
}
developPath, err := BranchWorkspacePath(normalized.WorkspaceBasePath, normalized.RepoDirName, BranchNameDevelop)
if err != nil {
return ProvisionPlan{}, err
}
defaultSlot, err := SlotWorkspacePath(normalized.WorkspaceBasePath, normalized.RepoDirName, DefaultSlotIndex)
if err != nil {
return ProvisionPlan{}, err
}
return ProvisionPlan{
ProjectWorkspaceRoot: root,
MainBranchPath: mainPath,
DevelopBranchPath: developPath,
DefaultSlotPath: defaultSlot,
}, nil
}
// 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
}