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