Monorepo for Tangled — https://tangled.org
at spindle-workflow 142 lines 3.8 kB view raw
1package steps 2 3import ( 4 "fmt" 5 "strings" 6 7 "tangled.org/core/api/tangled" 8 "tangled.org/core/workflow" 9) 10 11// BuildCloneCommands generates git clone commands from pipeline trigger metadata 12// Returns engine-agnostic command strings that engines can execute in their own way 13func BuildCloneCommands(cfg CloneConfig) (*CloneCommands, error) { 14 // Check if cloning should be skipped 15 if cfg.Workflow.Clone != nil && cfg.Workflow.Clone.Skip { 16 return &CloneCommands{Skip: true}, nil 17 } 18 19 // Extract commit SHA based on trigger type 20 commitSHA, err := extractCommitSHA(cfg.TriggerMetadata) 21 if err != nil { 22 return nil, fmt.Errorf("failed to extract commit SHA: %w", err) 23 } 24 25 // Build repository URL 26 repoURL := buildRepoURL(cfg.TriggerMetadata, cfg.DevMode) 27 28 // Set default workspace if not provided 29 workspaceDir := cfg.WorkspaceDir 30 if workspaceDir == "" { 31 workspaceDir = "/tangled/workspace" 32 } 33 34 // Build individual git commands 35 initCmd := fmt.Sprintf("git init %s", workspaceDir) 36 remoteCmd := fmt.Sprintf("git remote add origin %s", repoURL) 37 38 // Build fetch command with options 39 var cloneOpts tangled.Pipeline_CloneOpts 40 if cfg.Workflow.Clone != nil { 41 cloneOpts = *cfg.Workflow.Clone 42 } 43 fetchArgs := buildFetchArgs(cloneOpts, commitSHA) 44 fetchCmd := fmt.Sprintf("git fetch %s", strings.Join(fetchArgs, " ")) 45 46 checkoutCmd := "git checkout FETCH_HEAD" 47 48 // Combine all commands 49 allCmds := []string{ 50 initCmd, 51 fmt.Sprintf("cd %s", workspaceDir), 52 remoteCmd, 53 fetchCmd, 54 checkoutCmd, 55 } 56 57 return &CloneCommands{ 58 Init: initCmd, 59 Remote: remoteCmd, 60 Fetch: fetchCmd, 61 Checkout: checkoutCmd, 62 All: allCmds, 63 RepoURL: repoURL, 64 CommitSHA: commitSHA, 65 Skip: false, 66 }, nil 67} 68 69// extractCommitSHA extracts the commit SHA from trigger metadata based on trigger type 70func extractCommitSHA(tr tangled.Pipeline_TriggerMetadata) (string, error) { 71 switch workflow.TriggerKind(tr.Kind) { 72 case workflow.TriggerKindPush: 73 if tr.Push == nil { 74 return "", fmt.Errorf("push trigger metadata is nil") 75 } 76 return tr.Push.NewSha, nil 77 78 case workflow.TriggerKindPullRequest: 79 if tr.PullRequest == nil { 80 return "", fmt.Errorf("pull request trigger metadata is nil") 81 } 82 return tr.PullRequest.SourceSha, nil 83 84 case workflow.TriggerKindManual: 85 // Manual triggers don't have an explicit SHA in the metadata 86 // For now, return empty string - could be enhanced to fetch from default branch 87 // TODO: Implement manual trigger SHA resolution (fetch default branch HEAD) 88 return "", nil 89 90 default: 91 return "", fmt.Errorf("unknown trigger kind: %s", tr.Kind) 92 } 93} 94 95// buildRepoURL constructs the repository URL from trigger metadata 96func buildRepoURL(tr tangled.Pipeline_TriggerMetadata, devMode bool) string { 97 if tr.Repo == nil { 98 return "" 99 } 100 101 // Determine protocol 102 scheme := "https://" 103 if devMode { 104 scheme = "http://" 105 } 106 107 // Get host from knot 108 host := tr.Repo.Knot 109 110 // In dev mode, replace localhost with host.docker.internal for Docker networking 111 if devMode && strings.Contains(host, "localhost") { 112 host = strings.ReplaceAll(host, "localhost", "host.docker.internal") 113 } 114 115 // Build URL: {scheme}{knot}/{did}/{repo} 116 return fmt.Sprintf("%s%s/%s/%s", scheme, host, tr.Repo.Did, tr.Repo.Repo) 117} 118 119// buildFetchArgs constructs the arguments for git fetch based on clone options 120func buildFetchArgs(clone tangled.Pipeline_CloneOpts, sha string) []string { 121 args := []string{} 122 123 // Set fetch depth (default to 1 for shallow clone) 124 depth := clone.Depth 125 if depth == 0 { 126 depth = 1 127 } 128 args = append(args, fmt.Sprintf("--depth=%d", depth)) 129 130 // Add submodules if requested 131 if clone.Submodules { 132 args = append(args, "--recurse-submodules=yes") 133 } 134 135 // Add remote and SHA 136 args = append(args, "origin") 137 if sha != "" { 138 args = append(args, sha) 139 } 140 141 return args 142}