1package models
2
3import (
4 "fmt"
5 "path"
6 "strings"
7
8 "tangled.sh/tangled.sh/core/api/tangled"
9 "tangled.sh/tangled.sh/core/workflow"
10)
11
12func nixConfStep() Step {
13 setupCmd := `echo 'extra-experimental-features = nix-command flakes' >> /etc/nix/nix.conf
14echo 'build-users-group = ' >> /etc/nix/nix.conf`
15 return Step{
16 Command: setupCmd,
17 Name: "Configure Nix",
18 }
19}
20
21// cloneOptsAsSteps processes clone options and adds corresponding steps
22// to the beginning of the workflow's step list if cloning is not skipped.
23//
24// the steps to do here are:
25// - git init
26// - git remote add origin <url>
27// - git fetch --depth=<d> --recurse-submodules=<yes|no> <sha>
28// - git checkout FETCH_HEAD
29func cloneStep(twf tangled.Pipeline_Workflow, tr tangled.Pipeline_TriggerMetadata, dev bool) Step {
30 if twf.Clone.Skip {
31 return Step{}
32 }
33
34 var commands []string
35
36 // initialize git repo in workspace
37 commands = append(commands, "git init")
38
39 // add repo as git remote
40 scheme := "https://"
41 if dev {
42 scheme = "http://"
43 tr.Repo.Knot = strings.ReplaceAll(tr.Repo.Knot, "localhost", "host.docker.internal")
44 }
45 url := scheme + path.Join(tr.Repo.Knot, tr.Repo.Did, tr.Repo.Repo)
46 commands = append(commands, fmt.Sprintf("git remote add origin %s", url))
47
48 // run git fetch
49 {
50 var fetchArgs []string
51
52 // default clone depth is 1
53 depth := 1
54 if twf.Clone.Depth > 1 {
55 depth = int(twf.Clone.Depth)
56 }
57 fetchArgs = append(fetchArgs, fmt.Sprintf("--depth=%d", depth))
58
59 // optionally recurse submodules
60 if twf.Clone.Submodules {
61 fetchArgs = append(fetchArgs, "--recurse-submodules=yes")
62 }
63
64 // set remote to fetch from
65 fetchArgs = append(fetchArgs, "origin")
66
67 // set revision to checkout
68 switch workflow.TriggerKind(tr.Kind) {
69 case workflow.TriggerKindManual:
70 // TODO: unimplemented
71 case workflow.TriggerKindPush:
72 fetchArgs = append(fetchArgs, tr.Push.NewSha)
73 case workflow.TriggerKindPullRequest:
74 fetchArgs = append(fetchArgs, tr.PullRequest.SourceSha)
75 }
76
77 commands = append(commands, fmt.Sprintf("git fetch %s", strings.Join(fetchArgs, " ")))
78 }
79
80 // run git checkout
81 commands = append(commands, "git checkout FETCH_HEAD")
82
83 cloneStep := Step{
84 Command: strings.Join(commands, "\n"),
85 Name: "Clone repository into workspace",
86 }
87 return cloneStep
88}
89
90// dependencyStep processes dependencies defined in the workflow.
91// For dependencies using a custom registry (i.e. not nixpkgs), it collects
92// all packages and adds a single 'nix profile install' step to the
93// beginning of the workflow's step list.
94func dependencyStep(twf tangled.Pipeline_Workflow) *Step {
95 var customPackages []string
96
97 for _, d := range twf.Dependencies {
98 registry := d.Registry
99 packages := d.Packages
100
101 if registry == "nixpkgs" {
102 continue
103 }
104
105 if len(packages) == 0 {
106 customPackages = append(customPackages, registry)
107 }
108 // collect packages from custom registries
109 for _, pkg := range packages {
110 customPackages = append(customPackages, fmt.Sprintf("'%s#%s'", registry, pkg))
111 }
112 }
113
114 if len(customPackages) > 0 {
115 installCmd := "nix --extra-experimental-features nix-command --extra-experimental-features flakes profile install"
116 cmd := fmt.Sprintf("%s %s", installCmd, strings.Join(customPackages, " "))
117 installStep := Step{
118 Command: cmd,
119 Name: "Install custom dependencies",
120 Environment: map[string]string{
121 "NIX_NO_COLOR": "1",
122 "NIX_SHOW_DOWNLOAD_PROGRESS": "0",
123 },
124 }
125 return &installStep
126 }
127 return nil
128}