diff --git a/pkgs/oizys/oizys-go/cmd/boot.go b/pkgs/oizys/oizys-go/cmd/boot.go index 09230d4..d862f33 100644 --- a/pkgs/oizys/oizys-go/cmd/boot.go +++ b/pkgs/oizys/oizys-go/cmd/boot.go @@ -1,6 +1,8 @@ package cmd import ( + "oizys/internal/oizys" + "github.com/spf13/cobra" ) diff --git a/pkgs/oizys/oizys-go/cmd/build.go b/pkgs/oizys/oizys-go/cmd/build.go index bd325c8..31c021e 100644 --- a/pkgs/oizys/oizys-go/cmd/build.go +++ b/pkgs/oizys/oizys-go/cmd/build.go @@ -1,6 +1,8 @@ package cmd import ( + "oizys/internal/oizys" + "github.com/spf13/cobra" ) @@ -12,11 +14,8 @@ var buildCmd = &cobra.Command{ }, } -var minimal bool - func init() { rootCmd.AddCommand(buildCmd) buildCmd.Flags().BoolVar(&nom, "nom", false, "display result with nom") - // buildCmd.Flags().BoolVar(&systemPath, "system-path", false, "build system path derivation") buildCmd.Flags().BoolVar(&minimal, "minimal", false, "use system dry-run to make build args") } diff --git a/pkgs/oizys/oizys-go/cmd/cache.go b/pkgs/oizys/oizys-go/cmd/cache.go index cc7a968..312532c 100644 --- a/pkgs/oizys/oizys-go/cmd/cache.go +++ b/pkgs/oizys/oizys-go/cmd/cache.go @@ -1,6 +1,8 @@ package cmd import ( + "oizys/internal/oizys" + "github.com/spf13/cobra" ) @@ -8,10 +10,13 @@ var cacheCmd = &cobra.Command{ Use: "cache", Short: "build and push to cachix", Run: func(cmd *cobra.Command, args []string) { + oizys.SetCache(cacheName) oizys.CacheBuild(args...) }, } +var cacheName string + func init() { cacheCmd.Flags().StringVarP( &cacheName, diff --git a/pkgs/oizys/oizys-go/cmd/checks.go b/pkgs/oizys/oizys-go/cmd/checks.go index fb599ca..cc55837 100644 --- a/pkgs/oizys/oizys-go/cmd/checks.go +++ b/pkgs/oizys/oizys-go/cmd/checks.go @@ -1,6 +1,8 @@ package cmd import ( + "oizys/internal/oizys" + "github.com/spf13/cobra" ) diff --git a/pkgs/oizys/oizys-go/cmd/ci.go b/pkgs/oizys/oizys-go/cmd/ci.go index 7c6ebbf..94870ab 100644 --- a/pkgs/oizys/oizys-go/cmd/ci.go +++ b/pkgs/oizys/oizys-go/cmd/ci.go @@ -1,6 +1,8 @@ package cmd import ( + "oizys/internal/oizys" + "github.com/spf13/cobra" ) diff --git a/pkgs/oizys/oizys-go/cmd/dry.go b/pkgs/oizys/oizys-go/cmd/dry.go index 0649aef..074b2b7 100644 --- a/pkgs/oizys/oizys-go/cmd/dry.go +++ b/pkgs/oizys/oizys-go/cmd/dry.go @@ -1,6 +1,8 @@ package cmd import ( + "oizys/internal/oizys" + "github.com/spf13/cobra" ) @@ -8,11 +10,11 @@ var dryCmd = &cobra.Command{ Use: "dry", Short: "poor man's nix flake check", Run: func(cmd *cobra.Command, args []string) { - oizys.NixDryRun(verbose, args...) + oizys.Dry(verbose, minimal, args...) }, } func init() { rootCmd.AddCommand(dryCmd) - + dryCmd.Flags().BoolVarP(&minimal, "minimal", "m", false, "use system dry-run to make build args") } diff --git a/pkgs/oizys/oizys-go/cmd/output.go b/pkgs/oizys/oizys-go/cmd/output.go index fc018f7..7eafba9 100644 --- a/pkgs/oizys/oizys-go/cmd/output.go +++ b/pkgs/oizys/oizys-go/cmd/output.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/spf13/cobra" + "oizys/internal/oizys" ) var outputCmd = &cobra.Command{ diff --git a/pkgs/oizys/oizys-go/cmd/root.go b/pkgs/oizys/oizys-go/cmd/root.go index b5953b0..fb18888 100644 --- a/pkgs/oizys/oizys-go/cmd/root.go +++ b/pkgs/oizys/oizys-go/cmd/root.go @@ -3,7 +3,7 @@ package cmd import ( "os" - o "oizys/internal/oizys" + "oizys/internal/oizys" "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/log" @@ -31,15 +31,13 @@ func Execute() { var ( flake string host string - cacheName string verbose bool nom bool systemPath bool resetCache bool + minimal bool ) -var oizys = o.NewOizys() - var rootCmd = &cobra.Command{ Use: "oizys", Short: "nix begat oizys", @@ -48,7 +46,12 @@ var rootCmd = &cobra.Command{ log.Info("running with verbose mode") log.SetLevel(log.DebugLevel) } - oizys.Set(flake, host, cacheName, verbose, systemPath, resetCache) + oizys.SetFlake(flake) + oizys.SetHost(host) + oizys.SetCache(cacheName) // TODO: move + oizys.SetVerbose(verbose) + oizys.SetResetCache(resetCache) + oizys.CheckFlake() }, } diff --git a/pkgs/oizys/oizys-go/cmd/switch.go b/pkgs/oizys/oizys-go/cmd/switch.go index 9cce80a..2fe49b5 100644 --- a/pkgs/oizys/oizys-go/cmd/switch.go +++ b/pkgs/oizys/oizys-go/cmd/switch.go @@ -1,6 +1,8 @@ package cmd import ( + "oizys/internal/oizys" + "github.com/spf13/cobra" ) diff --git a/pkgs/oizys/oizys-go/cmd/update.go b/pkgs/oizys/oizys-go/cmd/update.go index acd581b..0eaaf89 100644 --- a/pkgs/oizys/oizys-go/cmd/update.go +++ b/pkgs/oizys/oizys-go/cmd/update.go @@ -1,6 +1,8 @@ package cmd import ( + "oizys/internal/oizys" + "github.com/spf13/cobra" ) diff --git a/pkgs/oizys/oizys-go/internal/oizys/cmd.go b/pkgs/oizys/oizys-go/internal/oizys/cmd.go new file mode 100644 index 0000000..7428a1a --- /dev/null +++ b/pkgs/oizys/oizys-go/internal/oizys/cmd.go @@ -0,0 +1,48 @@ +package oizys + +import ( + "fmt" + "os" + "os/exec" + "strings" + "time" + + "github.com/briandowns/spinner" + "github.com/charmbracelet/log" +) + +func logCmd(cmd *exec.Cmd) { + log.Debugf("CMD: %s", strings.Join(cmd.Args, " ")) +} + +func cmdOutputWithSpinner(cmd *exec.Cmd, msg string, stderr bool) (output []byte, err error) { + logCmd(cmd) + s := startSpinner(msg) + if stderr { + output, err = cmd.CombinedOutput() + } else { + output, err = cmd.Output() + } + s.Stop() + return +} + +func startSpinner(msg string) *spinner.Spinner { + s := spinner.New( + spinner.CharSets[14], + 100*time.Millisecond, + spinner.WithSuffix(fmt.Sprintf(" %s", msg)), + spinner.WithColor("fgHiMagenta"), + ) + s.Start() + return s +} + +func exitWithCommand(cmd *exec.Cmd) { + logCmd(cmd) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + log.Fatal("final command failed", "err", err) + } +} diff --git a/pkgs/oizys/oizys-go/internal/oizys/display.go b/pkgs/oizys/oizys-go/internal/oizys/display.go new file mode 100644 index 0000000..5e454a2 --- /dev/null +++ b/pkgs/oizys/oizys-go/internal/oizys/display.go @@ -0,0 +1,101 @@ +package oizys + +import ( + "fmt" + "os" + "strings" + + "github.com/charmbracelet/lipgloss" + "github.com/charmbracelet/log" + "golang.org/x/term" +) + +// TODO: seperate parsing and displaying of packages +func terminalSize() (int, int) { + fd := os.Stdout.Fd() + if !term.IsTerminal(int(fd)) { + log.Error("failed to get terminal size") + return 80, 0 + } + w, h, err := term.GetSize(int(fd)) + if err != nil { + log.Fatal(err) + } + return w, h +} + +type packages struct { + desc string + names []string + pad int +} + +func parsePackages(lines []string, desc string) *packages { + w, _ := terminalSize() + maxAcceptable := (w / 4) - 1 + maxLen := 0 + names := make([]string, len(lines)) + for i, pkg := range lines { + s := strings.SplitN(pkg, "-", 2) + if len(s) != 2 { + log.Fatalf("failed to trim hash path from this line: %s\n ", pkg) + } + name := ellipsis(strings.Replace(s[1], ".drv", "", 1), maxAcceptable) + if nameLen := len(name); nameLen > maxLen { + maxLen = nameLen + } + names[i] = name + } + return &packages{names: names, pad: maxLen + 1, desc: desc} +} + +func ellipsis(s string, maxLen int) string { + runes := []rune(s) + if len(runes) <= maxLen { + return s + } + if maxLen < 3 { + maxLen = 3 + } + return string(runes[0:maxLen-3]) + "..." +} + +func (p *packages) show(verbose bool) { + p.summary() + if !verbose || (len(p.names) == 0) { + return + } + + pkgs := p.names + w, _ := terminalSize() + nCols := w / p.pad + fmt.Printf("%s\n", strings.Repeat("-", w)) + for i, pkg := range pkgs { + fmt.Printf("%-*s", p.pad, pkg) + if (i+1)%nCols == 0 { + fmt.Println() + } + } + fmt.Println() +} + +func (p *packages) summary() { + fmt.Printf("%s: %s\n", + p.desc, + lipgloss.NewStyle(). + Bold(true). + Foreground(lipgloss.Color("6")). + Render(fmt.Sprint(len(p.names))), + ) +} + +func showFailedOutput(buf []byte) { + arrow := lipgloss. + NewStyle(). + Bold(true). + Foreground(lipgloss.Color("9")). + Render("->") + for _, line := range strings.Split(strings.TrimSpace(string(buf)), "\n") { + fmt.Println(arrow, line) + } +} diff --git a/pkgs/oizys/oizys-go/internal/oizys/main.go b/pkgs/oizys/oizys-go/internal/oizys/main.go index 1cffd12..6f2cf5f 100644 --- a/pkgs/oizys/oizys-go/internal/oizys/main.go +++ b/pkgs/oizys/oizys-go/internal/oizys/main.go @@ -7,17 +7,20 @@ import ( "io/fs" "os" "os/exec" - "sort" "strings" - "time" "github.com/charmbracelet/lipgloss" - "golang.org/x/term" "github.com/briandowns/spinner" "github.com/charmbracelet/log" ) +var o *Oizys + +func init() { + o = New() +} + // verbose vs debug? type Oizys struct { flake string @@ -30,12 +33,12 @@ type Oizys struct { resetCache bool } -func NewOizys() *Oizys { +func New() *Oizys { o := new(Oizys) o.cache = "daylin" hostname, err := os.Hostname() if err != nil { - log.Fatal(err) + log.Fatal("failed to determine hostname", "err", err) } o.host = hostname oizysDir, ok := os.LookupEnv("OIZYS_DIR") @@ -51,6 +54,32 @@ func NewOizys() *Oizys { return o } +func SetFlake(path string) { + if path != "" { + o.flake = path + } +} + +func SetCache(name string) { + if name != "" { + o.cache = name + } +} + +func SetHost(name string) { + if name != "" { + o.host = name + } +} + +func SetVerbose(v bool) { + o.verbose = v +} + +func SetResetCache(reset bool) { + o.resetCache = reset +} + type Derivation struct { InputDrvs map[string]interface{} } @@ -68,12 +97,9 @@ func parseSystemPath(derivation map[string]Derivation) (string, error) { // recreating this command // nix derivation show `oizys output` | jq -r '.[].inputDrvs | with_entries(select(.key|match("system-path";"i"))) | keys | .[]' -func (o *Oizys) getSystemPath() string { +func getSystemPath() string { cmd := exec.Command("nix", "derivation", "show", o.nixosConfigAttr()) - logCmd(cmd) - s := nixSpinner(o.host) - out, err := cmd.Output() - s.Stop() + out, err := cmdOutputWithSpinner(cmd, "running nix derivation show for full system", false) if err != nil { log.Fatal("failed to evalute nixosConfiguration for system-path.drv", "err", err) } @@ -97,117 +123,33 @@ func (o *Oizys) nixosConfigAttr() string { ) } -func (o *Oizys) Output() string { +func Output() string { if o.systemPath { - return o.getSystemPath() + return getSystemPath() } else { return o.nixosConfigAttr() } } -func (o *Oizys) Set( - flake, host, cache string, - verbose, systemPath, resetCache bool, -) { - if host != "" { - o.host = host - } - if flake != "" { - o.flake = flake - } - if cache != "" { - o.cache = cache - } - o.verbose = verbose - o.systemPath = systemPath - o.resetCache = resetCache -} +// func (o *Oizys) Set( +// flake, host, cache string, +// verbose, systemPath, resetCache bool, +// ) { +// if host != "" { +// o.host = host +// } +// if flake != "" { +// o.flake = flake +// } +// if cache != "" { +// o.cache = cache +// } +// o.verbose = verbose +// o.systemPath = systemPath +// o.resetCache = resetCache +// } -// TODO: seperate parsing and displaying of packages -func terminalSize() (int, int) { - fd := os.Stdout.Fd() - if !term.IsTerminal(int(fd)) { - log.Error("failed to get terminal size") - return 80, 0 - // log.Fatal("failed to get terminal size") - } - w, h, err := term.GetSize(int(fd)) - if err != nil { - log.Fatal(err) - } - return w, h -} - -type packages struct { - desc string - names []string - pad int -} - -func parsePackages(lines []string, desc string) *packages { - w, _ := terminalSize() - maxAcceptable := (w / 4) - 1 - maxLen := 0 - names := make([]string, len(lines)) - for i, pkg := range lines { - s := strings.SplitN(pkg, "-", 2) - if len(s) != 2 { - log.Fatalf("failed to trim hash path from this line: %s\n ", pkg) - } - name := ellipsis(strings.Replace(s[1], ".drv", "", 1), maxAcceptable) - if nameLen := len(name); nameLen > maxLen { - maxLen = nameLen - } - names[i] = name - } - return &packages{names: names, pad: maxLen + 1, desc: desc} -} - -func ellipsis(s string, maxLen int) string { - runes := []rune(s) - if len(runes) <= maxLen { - return s - } - if maxLen < 3 { - maxLen = 3 - } - return string(runes[0:maxLen-3]) + "..." -} - -func (p *packages) show(verbose bool) { - p.summary() - if !verbose || (len(p.names) == 0) { - return - } - - pkgs := p.names - w, _ := terminalSize() - nCols := w / p.pad - fmt.Printf("%s\n", strings.Repeat("-", w)) - for i, pkg := range pkgs { - fmt.Printf("%-*s", p.pad, pkg) - if (i+1)%nCols == 0 { - fmt.Println() - } - } - fmt.Println() -} - -func (p *packages) summary() { - fmt.Printf("%s: %s\n", - p.desc, - lipgloss.NewStyle(). - Bold(true). - Foreground(lipgloss.Color("6")). - Render(fmt.Sprint(len(p.names))), - ) -} - -func logCmd(cmd *exec.Cmd) { - log.Debugf("CMD: %s", strings.Join(cmd.Args, " ")) -} - -func (o *Oizys) git(rest ...string) *exec.Cmd { +func git(rest ...string) *exec.Cmd { args := []string{"-C", o.flake} args = append(args, rest...) cmd := exec.Command("git", args...) @@ -215,19 +157,8 @@ func (o *Oizys) git(rest ...string) *exec.Cmd { return cmd } -func showFailedOutput(buf []byte) { - arrow := lipgloss. - NewStyle(). - Bold(true). - Foreground(lipgloss.Color("9")). - Render("->") - for _, line := range strings.Split(strings.TrimSpace(string(buf)), "\n") { - fmt.Println(arrow, line) - } -} - -func (o *Oizys) GitPull() { - cmdOutput, err := o.git("status", "--porcelain").Output() +func GitPull() { + cmdOutput, err := git("status", "--porcelain").Output() if err != nil { log.Fatal(err) } @@ -238,7 +169,7 @@ func (o *Oizys) GitPull() { os.Exit(1) } - cmdOutput, err = o.git("pull").CombinedOutput() + cmdOutput, err = git("pull").CombinedOutput() if err != nil { showFailedOutput(cmdOutput) log.Fatal(err) @@ -301,24 +232,38 @@ func showDryRunResult(nixOutput string, verbose bool) { toFetch.show(verbose) } -func (o *Oizys) NixDryRun(verbose bool, rest ...string) { - args := []string{ - "build", o.nixosConfigAttr(), "--dry-run", +func Dry(verbose bool, minimal bool, rest ...string) { + cmd := exec.Command("nix", "build", "--dry-run") + cmd.Args = append(cmd.Args, rest...) + var spinnerMsg string + if minimal { + drvs := systemPathDrvsToBuild() + if len(drvs) == 0 { + log.Info("no packages in minimal set to build") + os.Exit(0) + } + cmd.Args = append(cmd.Args, drvs...) + spinnerMsg = "evaluting for minimal build needs" + } else { + log.Debug("evalutating full nixosConfiguration") + cmd.Args = append(cmd.Args, o.nixosConfigAttr()) + spinnerMsg = fmt.Sprintf("%s %s", "evaluating derivation for:", + lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("6")).Render(o.host), + ) } - args = append(args, rest...) - cmd := exec.Command("nix", args...) - s := nixSpinner(o.host) - result, err := cmd.CombinedOutput() - s.Stop() + result, err := cmdOutputWithSpinner(cmd, spinnerMsg, true) if err != nil { - fmt.Println(string(result)) - log.Fatal(err) + log.Fatal("failed to dry-run nix build", "err", err, "output", string(result)) + } + if minimal { + fmt.Println(string(result)) + } else { + showDryRunResult(string(result), verbose) } - showDryRunResult(string(result), verbose) } // / Setup command completely differently here -func (o *Oizys) NixosRebuild(subcmd string, rest ...string) { +func NixosRebuild(subcmd string, rest ...string) { cmd := exec.Command("sudo", "nixos-rebuild", subcmd, @@ -329,19 +274,10 @@ func (o *Oizys) NixosRebuild(subcmd string, rest ...string) { if o.verbose { cmd.Args = append(cmd.Args, "--print-build-logs") } - runCommand(cmd) + exitWithCommand(cmd) } -func runCommand(cmd *exec.Cmd) { - logCmd(cmd) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - log.Fatal(err) - } -} - -func (o *Oizys) NixBuild(nom bool, minimal bool, rest ...string) { +func NixBuild(nom bool, minimal bool, rest ...string) { var cmdName string if nom { cmdName = "nom" @@ -349,7 +285,6 @@ func (o *Oizys) NixBuild(nom bool, minimal bool, rest ...string) { cmdName = "nix" } cmd := exec.Command(cmdName, "build") - cmd.Args = append(cmd.Args, rest...) if o.resetCache { cmd.Args = append(cmd.Args, "--narinfo-cache-positive-ttl", "0") @@ -359,7 +294,7 @@ func (o *Oizys) NixBuild(nom bool, minimal bool, rest ...string) { // } if minimal { log.Debug("populating args with derivations not already built") - drvs := o.systemPathDrvsToBuild() + drvs := systemPathDrvsToBuild() if len(drvs) == 0 { log.Info("nothing to build. exiting...") os.Exit(0) @@ -367,7 +302,7 @@ func (o *Oizys) NixBuild(nom bool, minimal bool, rest ...string) { cmd.Args = append(cmd.Args, drvs...) } - runCommand(cmd) + exitWithCommand(cmd) } var ignoredMap = stringSliceToMap( @@ -395,10 +330,10 @@ var ignoredMap = stringSliceToMap( }, ) -func drvIsIgnored(drv string) bool { +func drvNotIgnored(drv string) bool { s := strings.SplitN(strings.Replace(drv, ".drv", "", 1), "-", 2) _, ok := ignoredMap[s[len(s)-1]] - return ok + return !ok } func stringSliceToMap(slice []string) map[string]struct{} { @@ -419,40 +354,71 @@ func drvsToInputs(derivation map[string]Derivation) []string { return drvs } -// v2 -func (o *Oizys) systemPathDrvsToBuild() []string { - log.Debug("getting system-path build-only deps") - systemPathDrv := fmt.Sprintf("%s^*", o.getSystemPath()) - derivationCmd := exec.Command("nix", "derivation", "show", systemPathDrv) - logCmd(derivationCmd) - output, err := derivationCmd.Output() - if err != nil { - log.Fatal("failed to evaluate", "drv", systemPathDrv) +// compute the overlap between two slices of strings +func overlapStrings(a []string, b []string) []string { + var overlap []string + set := stringSliceToMap(a) + for _, s := range b { + _, ok := set[s] + if ok { + overlap = append(overlap, s) + } } + return overlap +} - // TODO: abstract this? +func nixDerivationShowToInputs(output []byte) []string { var derivation map[string]Derivation if err := json.Unmarshal(output, &derivation); err != nil { log.Fatal(err) } - systemPathInputDrvs := stringSliceToMap(drvsToInputs(derivation)) + return drvsToInputs(derivation) +} - // get to build packages for full system - systemCmd := exec.Command("nix", "build", o.nixosConfigAttr(), "--dry-run") - logCmd(systemCmd) - result, err := systemCmd.CombinedOutput() - if err != nil { - log.Fatal("failed to dry-run build full system", "err", err) - } - toBuild, _ := parseDryRun2(string(result)) - - var toActuallyBuild []string - for _, drv := range toBuild { - _, ok := systemPathInputDrvs[drv] - if ok && !drvIsIgnored(drv) { - toActuallyBuild = append(toActuallyBuild, drv) +func filter[T any](ss []T, test func(T) bool) (ret []T) { + for _, s := range ss { + if test(s) { + ret = append(ret, s) } } + return +} + +func toBuildNixosConfiguration() []string { + systemCmd := exec.Command("nix", "build", o.nixosConfigAttr(), "--dry-run") + result, err := cmdOutputWithSpinner( + systemCmd, + fmt.Sprintf("running dry build for: %s", o.nixosConfigAttr()), + true, + ) + if err != nil { + log.Fatal("failed to dry-run build system", "err", err) + } + toBuild, _ := parseDryRun2(string(result)) + return toBuild +} + +func systemPathDerivationShow() []string { + systemPathDrv := fmt.Sprintf("%s^*", getSystemPath()) + derivationCmd := exec.Command("nix", "derivation", "show", systemPathDrv) + output, err := cmdOutputWithSpinner( + derivationCmd, + fmt.Sprintf("evaluating system path: %s", systemPathDrv), + false) + if err != nil { + log.Fatal("failed to evaluate", "drv", systemPathDrv) + } + return nixDerivationShowToInputs(output) +} + +func systemPathDrvsToBuild() []string { + toBuild := toBuildNixosConfiguration() + systemPathInputDrvs := systemPathDerivationShow() + + toActuallyBuild := filter( + overlapStrings(systemPathInputDrvs, toBuild), + drvNotIgnored, + ) drvs := make([]string, len(toActuallyBuild)) for i, pkg := range toActuallyBuild { @@ -461,11 +427,6 @@ func (o *Oizys) systemPathDrvsToBuild() []string { return drvs } -func contains(s []string, search string) bool { - i := sort.SearchStrings(s, search) - return i < len(s) && s[i] == search -} - func (o *Oizys) writeToGithubStepSummary(txt string) { f, err := os.OpenFile(o.githubSummary, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { @@ -513,14 +474,14 @@ func (o *Oizys) checkPath(name string) string { return fmt.Sprintf("%s#checks.x86_64-linux.%s", o.flake, name) } -func (o *Oizys) Checks(nom bool, rest ...string) { +func Checks(nom bool, rest ...string) { checks := o.getChecks() for _, check := range checks { - o.NixBuild(nom, false, o.checkPath(check)) + NixBuild(nom, false, o.checkPath(check)) } } -func (o *Oizys) CacheBuild(rest ...string) { +func CacheBuild(rest ...string) { args := []string{ "watch-exec", o.cache, "--", "nix", "build", o.nixosConfigAttr(), "--print-build-logs", @@ -528,10 +489,10 @@ func (o *Oizys) CacheBuild(rest ...string) { } args = append(args, rest...) cmd := exec.Command("cachix", args...) - runCommand(cmd) + exitWithCommand(cmd) } -func (o *Oizys) CheckFlake() { +func CheckFlake() { if _, ok := os.LookupEnv("OIZYS_SKIP_CHECK"); !ok { if _, err := os.Stat(o.flake); errors.Is(err, fs.ErrNotExist) { log.Fatalf("path to flake: %s does not exist", o.flake) @@ -539,23 +500,17 @@ func (o *Oizys) CheckFlake() { } } -func (o *Oizys) CI(rest ...string) { +func CI(rest ...string) { args := []string{"workflow", "run", "build.yml", "-F", fmt.Sprintf("hosts=%s", o.host)} args = append(args, rest...) cmd := exec.Command("gh", args...) - runCommand(cmd) + exitWithCommand(cmd) } +// TODO: deprecate func nixSpinner(host string) *spinner.Spinner { msg := fmt.Sprintf("%s %s", " evaluating derivation for:", lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("6")).Render(host), ) - s := spinner.New( - spinner.CharSets[14], - 100*time.Millisecond, - spinner.WithSuffix(msg), - spinner.WithColor("fgHiMagenta"), - ) - s.Start() - return s + return startSpinner(msg) }