Monorepo for Tangled
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 163 lines 4.2 kB view raw
1package models 2 3import ( 4 "fmt" 5 "strings" 6 7 "tangled.org/core/api/tangled" 8 "tangled.org/core/workflow" 9) 10 11type CloneStep struct { 12 name string 13 kind StepKind 14 commands []string 15} 16 17func (s CloneStep) Name() string { 18 return s.name 19} 20 21func (s CloneStep) Commands() []string { 22 return s.commands 23} 24 25func (s CloneStep) Command() string { 26 return strings.Join(s.commands, "\n") 27} 28 29func (s CloneStep) Kind() StepKind { 30 return s.kind 31} 32 33// BuildCloneStep generates git clone commands. 34// The caller must ensure the current working directory is set to the desired 35// workspace directory before executing these commands. 36// 37// The generated commands are: 38// - git init 39// - git remote add origin <url> 40// - git fetch --depth=<d> --recurse-submodules=<yes|no> <sha> 41// - git checkout FETCH_HEAD 42// 43// Supports all trigger types (push, PR, manual) and clone options. 44func BuildCloneStep(twf tangled.Pipeline_Workflow, tr tangled.Pipeline_TriggerMetadata, dev bool) CloneStep { 45 if twf.Clone != nil && twf.Clone.Skip { 46 return CloneStep{} 47 } 48 49 commitSHA, err := extractCommitSHA(tr) 50 if err != nil { 51 return CloneStep{ 52 kind: StepKindSystem, 53 name: "Clone repository into workspace (error)", 54 commands: []string{fmt.Sprintf("echo 'Failed to get clone info: %s' && exit 1", err.Error())}, 55 } 56 } 57 58 repoURL := BuildRepoURL(tr.Repo) 59 60 if dev { 61 repoURL = RewriteLocalhost(repoURL, twf.Engine) 62 } 63 64 var cloneOpts tangled.Pipeline_CloneOpts 65 if twf.Clone != nil { 66 cloneOpts = *twf.Clone 67 } 68 fetchArgs := buildFetchArgs(cloneOpts, commitSHA) 69 70 return CloneStep{ 71 kind: StepKindSystem, 72 name: "Clone repository into workspace", 73 commands: []string{ 74 "git init", 75 fmt.Sprintf("git remote add origin %s", repoURL), 76 fmt.Sprintf("git fetch %s", strings.Join(fetchArgs, " ")), 77 "git checkout FETCH_HEAD", 78 }, 79 } 80} 81 82// extractCommitSHA extracts the commit SHA from trigger metadata based on trigger type 83func extractCommitSHA(tr tangled.Pipeline_TriggerMetadata) (string, error) { 84 switch workflow.TriggerKind(tr.Kind) { 85 case workflow.TriggerKindPush: 86 if tr.Push == nil { 87 return "", fmt.Errorf("push trigger metadata is nil") 88 } 89 return tr.Push.NewSha, nil 90 91 case workflow.TriggerKindPullRequest: 92 if tr.PullRequest == nil { 93 return "", fmt.Errorf("pull request trigger metadata is nil") 94 } 95 return tr.PullRequest.SourceSha, nil 96 97 case workflow.TriggerKindManual: 98 // Manual triggers don't have an explicit SHA in the metadata 99 // For now, return empty string - could be enhanced to fetch from default branch 100 // TODO: Implement manual trigger SHA resolution (fetch default branch HEAD) 101 return "", nil 102 103 default: 104 return "", fmt.Errorf("unknown trigger kind: %s", tr.Kind) 105 } 106} 107 108// BuildRepoURL constructs the repository URL from repo metadata. 109func BuildRepoURL(repo *tangled.Pipeline_TriggerRepo) string { 110 if repo == nil { 111 return "" 112 } 113 114 scheme := "https://" 115 // Get host from knot 116 host := repo.Knot 117 118 switch { 119 case repo.RepoDid != nil: 120 return fmt.Sprintf("%s%s/%s", scheme, host, *repo.RepoDid) 121 case repo.Repo != nil: 122 return fmt.Sprintf("%s%s/%s/%s", scheme, host, repo.Did, *repo.Repo) 123 default: 124 return "" 125 } 126} 127 128// RewriteLocalhost adapts a localhost repository URL for container/VM environments 129func RewriteLocalhost(repoURL string, engine string) string { 130 if !strings.Contains(repoURL, "localhost") { 131 return repoURL 132 } 133 repoURL = strings.ReplaceAll(repoURL, "https://", "http://") 134 if engine == "qemu" { 135 return strings.ReplaceAll(repoURL, "localhost", "10.0.2.2") 136 } 137 return strings.ReplaceAll(repoURL, "localhost", "host.docker.internal") 138} 139 140// buildFetchArgs constructs the arguments for git fetch based on clone options 141func buildFetchArgs(clone tangled.Pipeline_CloneOpts, sha string) []string { 142 args := []string{} 143 144 // Set fetch depth (default to 1 for shallow clone) 145 depth := clone.Depth 146 if depth == 0 { 147 depth = 1 148 } 149 args = append(args, fmt.Sprintf("--depth=%d", depth)) 150 151 // Add submodules if requested 152 if clone.Submodules { 153 args = append(args, "--recurse-submodules=yes") 154 } 155 156 // Add remote and SHA 157 args = append(args, "origin") 158 if sha != "" { 159 args = append(args, sha) 160 } 161 162 return args 163}