diff --git a/lib/default.nix b/lib/default.nix index e456fc8..35300e3 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -57,7 +57,7 @@ rec { oizys-nim = pkgs.callPackage ../pkgs/oizys/oizys-nim { }; oizys-rs = pkgs.callPackage ../pkgs/oizys/oizys-rs { }; oizys-go = pkgs.callPackage ../pkgs/oizys/oizys-go { }; - default = oizys-rs; + default = oizys-go; }); devShells = forAllSystems (pkgs: { default = pkgs.mkShell { diff --git a/pkgs/oizys/oizys-go/cmd/boot.go b/pkgs/oizys/oizys-go/cmd/boot.go index 96e0826..09230d4 100644 --- a/pkgs/oizys/oizys-go/cmd/boot.go +++ b/pkgs/oizys/oizys-go/cmd/boot.go @@ -2,15 +2,13 @@ package cmd import ( "github.com/spf13/cobra" - "oizys/pkg/oizys" ) var bootCmd = &cobra.Command{ Use: "boot", Short: "nixos rebuild boot", Run: func(cmd *cobra.Command, args []string) { - oizys.CheckFlake(flake) - oizys.NixosRebuild("boot", flake) + oizys.NixosRebuild("boot", args...) }, } diff --git a/pkgs/oizys/oizys-go/cmd/build.go b/pkgs/oizys/oizys-go/cmd/build.go index 7db8b75..544bfef 100644 --- a/pkgs/oizys/oizys-go/cmd/build.go +++ b/pkgs/oizys/oizys-go/cmd/build.go @@ -2,15 +2,13 @@ package cmd import ( "github.com/spf13/cobra" - "oizys/pkg/oizys" ) var buildCmd = &cobra.Command{ Use: "build", Short: "A brief description of your command", Run: func(cmd *cobra.Command, args []string) { - oizys.CheckFlake(flake) - oizys.NixBuild(oizys.Output(flake, host), args...) + oizys.NixBuild(args...) }, } diff --git a/pkgs/oizys/oizys-go/cmd/cache.go b/pkgs/oizys/oizys-go/cmd/cache.go index 97891e1..cc7a968 100644 --- a/pkgs/oizys/oizys-go/cmd/cache.go +++ b/pkgs/oizys/oizys-go/cmd/cache.go @@ -2,15 +2,13 @@ package cmd import ( "github.com/spf13/cobra" - "oizys/pkg/oizys" ) var cacheCmd = &cobra.Command{ Use: "cache", Short: "build and push to cachix", Run: func(cmd *cobra.Command, args []string) { - oizys.CheckFlake(flake) - oizys.CacheBuild(oizys.Output(flake, host), cacheName, args...) + oizys.CacheBuild(args...) }, } diff --git a/pkgs/oizys/oizys-go/cmd/dry.go b/pkgs/oizys/oizys-go/cmd/dry.go index cf802e9..cdd43d8 100644 --- a/pkgs/oizys/oizys-go/cmd/dry.go +++ b/pkgs/oizys/oizys-go/cmd/dry.go @@ -1,8 +1,6 @@ package cmd import ( - "oizys/pkg/oizys" - "github.com/spf13/cobra" ) @@ -10,8 +8,7 @@ var dryCmd = &cobra.Command{ Use: "dry", Short: "poor man's nix flake check", Run: func(cmd *cobra.Command, args []string) { - oizys.CheckFlake(flake) - oizys.NixDryRun(flake, host, verbose) + oizys.NixDryRun(verbose, args...) }, } diff --git a/pkgs/oizys/oizys-go/cmd/output.go b/pkgs/oizys/oizys-go/cmd/output.go index c2a74f2..7b833d5 100644 --- a/pkgs/oizys/oizys-go/cmd/output.go +++ b/pkgs/oizys/oizys-go/cmd/output.go @@ -4,15 +4,13 @@ import ( "fmt" "github.com/spf13/cobra" - "oizys/pkg/oizys" ) var outputCmd = &cobra.Command{ Use: "output", Short: "show nixosConfiguration attr", Run: func(cmd *cobra.Command, args []string) { - oizys.CheckFlake(flake) - fmt.Println(oizys.Output(flake, host)) + fmt.Println(oizys.Output()) }, } diff --git a/pkgs/oizys/oizys-go/cmd/root.go b/pkgs/oizys/oizys-go/cmd/root.go index 0d5ee98..800a183 100644 --- a/pkgs/oizys/oizys-go/cmd/root.go +++ b/pkgs/oizys/oizys-go/cmd/root.go @@ -1,43 +1,20 @@ package cmd import ( - "fmt" - "log" "os" cc "github.com/ivanpirog/coloredcobra" "github.com/spf13/cobra" + o "oizys/pkg" ) -func setFlake() { - if flake == "" { - oizysDir, ok := os.LookupEnv("OIZYS_DIR") - if !ok { - home := os.Getenv("HOME") - flake = fmt.Sprintf("%s/%s", home, "oizys") - } else { - flake = oizysDir - } - } -} - -func setHost() { - if host == "" { - hostname, err := os.Hostname() - if err != nil { - log.Fatal(err) - } - host = hostname - } -} - func Execute() { cc.Init(&cc.Config{ RootCmd: rootCmd, - Headings: cc.HiCyan + cc.Bold, + Headings: cc.HiMagenta + cc.Bold, Commands: cc.HiYellow + cc.Bold, Example: cc.Italic, - ExecName: cc.Bold, + ExecName: cc.HiYellow + cc.Bold, Flags: cc.Bold, NoExtraNewlines: true, NoBottomNewline: true, @@ -54,12 +31,14 @@ var ( cacheName string ) +var oizys = o.NewOizys() + var rootCmd = &cobra.Command{ Use: "oizys", Short: "nix begat oizys", PersistentPreRun: func(cmd *cobra.Command, args []string) { - setFlake() - setHost() + oizys.Update(flake, host, cacheName) + oizys.CheckFlake() }, } diff --git a/pkgs/oizys/oizys-go/cmd/switch.go b/pkgs/oizys/oizys-go/cmd/switch.go index 79e16a0..9cce80a 100644 --- a/pkgs/oizys/oizys-go/cmd/switch.go +++ b/pkgs/oizys/oizys-go/cmd/switch.go @@ -2,15 +2,13 @@ package cmd import ( "github.com/spf13/cobra" - "oizys/pkg/oizys" ) var switchCmd = &cobra.Command{ Use: "switch", Short: "nixos rebuild switch", Run: func(cmd *cobra.Command, args []string) { - oizys.CheckFlake(flake) - oizys.NixosRebuild("switch", flake, args...) + oizys.NixosRebuild("switch", args...) }, } diff --git a/pkgs/oizys/oizys-go/default.nix b/pkgs/oizys/oizys-go/default.nix index 6d0d710..fa3d00b 100644 --- a/pkgs/oizys/oizys-go/default.nix +++ b/pkgs/oizys/oizys-go/default.nix @@ -9,7 +9,7 @@ buildGoModule { version = "unstable"; src = lib.cleanSource ./.; - vendorHash = "sha256-Fcq8p/YItF5lx82PRg1/tksV7iCIS0xZZVWdpE3e7F0="; + vendorHash = "sha256-NCHU491j6fRfSk6LA9tS9yiuT/gZhPic46mNTVf1Jeg="; nativeBuildInputs = [ installShellFiles ]; diff --git a/pkgs/oizys/oizys-go/go.mod b/pkgs/oizys/oizys-go/go.mod index 727be12..4626489 100644 --- a/pkgs/oizys/oizys-go/go.mod +++ b/pkgs/oizys/oizys-go/go.mod @@ -3,32 +3,22 @@ module oizys go 1.22.2 require ( - github.com/charmbracelet/bubbles v0.18.0 - github.com/charmbracelet/bubbletea v0.26.1 - github.com/charmbracelet/lipgloss v0.10.0 + github.com/briandowns/spinner v1.23.0 github.com/ivanpirog/coloredcobra v1.0.1 + github.com/muesli/termenv v0.15.2 github.com/spf13/cobra v1.8.0 golang.org/x/term v0.19.0 ) require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/briandowns/spinner v1.23.0 // indirect - github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/fatih/color v1.16.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect - github.com/muesli/cancelreader v0.2.2 // indirect - github.com/muesli/reflow v0.3.0 // indirect - github.com/muesli/termenv v0.15.2 // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.19.0 // indirect - golang.org/x/text v0.3.8 // indirect ) diff --git a/pkgs/oizys/oizys-go/go.sum b/pkgs/oizys/oizys-go/go.sum index a47b955..7d5d1b0 100644 --- a/pkgs/oizys/oizys-go/go.sum +++ b/pkgs/oizys/oizys-go/go.sum @@ -2,16 +2,8 @@ github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiE github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/briandowns/spinner v1.23.0 h1:alDF2guRWqa/FOZZYWjlMIx2L6H0wyewPxo/CH4Pt2A= github.com/briandowns/spinner v1.23.0/go.mod h1:rPG4gmXeN3wQV/TsAY4w8lPdIM6RX3yqeBQJSrbXjuE= -github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= -github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= -github.com/charmbracelet/bubbletea v0.26.1 h1:xujcQeF73rh4jwu3+zhfQsvV18x+7zIjlw7/CYbzGJ0= -github.com/charmbracelet/bubbletea v0.26.1/go.mod h1:FzKr7sKoO8iFVcdIBM9J0sJOcQv5nDQaYwsee3kpbgo= -github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s= -github.com/charmbracelet/lipgloss v0.10.0/go.mod h1:Wig9DSfvANsxqkRsqj6x87irdy123SR4dOXlKa91ciE= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= -github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= @@ -30,20 +22,10 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= -github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= -github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= -github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= -github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= -github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= -github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= -github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= -github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -53,20 +35,15 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= -golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkgs/oizys/oizys-go/pkg/oizys.go b/pkgs/oizys/oizys-go/pkg/oizys.go new file mode 100644 index 0000000..9f4aff6 --- /dev/null +++ b/pkgs/oizys/oizys-go/pkg/oizys.go @@ -0,0 +1,242 @@ +package oizys + +import ( + "errors" + "fmt" + "io/fs" + "log" + "os" + "os/exec" + "strings" + + "github.com/muesli/termenv" + "golang.org/x/term" + + "time" + + "github.com/briandowns/spinner" +) + +type Oizys struct { + flake string + host string + cache string +} + +var output = termenv.NewOutput(os.Stdout) + +func NewOizys() *Oizys { + hostname, err := os.Hostname() + if err != nil { + log.Fatal(err) + } + flake := "" + oizysDir, ok := os.LookupEnv("OIZYS_DIR") + if !ok { + home := os.Getenv("HOME") + flake = fmt.Sprintf("%s/%s", home, "oizys") + } else { + flake = oizysDir + } + + return &Oizys{flake: flake, host: hostname, cache: "daylin"} +} + +func (o *Oizys) Output() string { + return fmt.Sprintf( + "%s#nixosConfigurations.%s.config.system.build.toplevel", + o.flake, + o.host, + ) +} + +func (o *Oizys) Update(flake string, host string, cache string) { + if host != "" { + o.host = host + } + if flake != "" { + o.flake = flake + } + if cache != "" { + o.cache = cache + } +} + +func terminalSize() (int, int) { + fd := os.Stdout.Fd() + if !term.IsTerminal(int(fd)) { + 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 { + names []string + pad int + desc string +} + +func parsePackages(buf string, desc string) *packages { + w, _ := terminalSize() + maxAcceptable := (w / 4) - 1 + maxLen := 0 + lines := strings.Split(strings.TrimSpace(buf), "\n")[1:] + names := make([]string, len(lines)) + for i, pkg := range lines { + s := strings.SplitN(pkg, "-", 2) + if len(s) != 2 { + log.Fatalln("failed to trim hash path from this line: ", 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 { + 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%nCols == 0 { + fmt.Println() + } + } + fmt.Println() +} + +func (p *packages) summary() { + fmt.Printf("%s: %s\n", + p.desc, + output.String(fmt.Sprint(len(p.names))).Bold().Foreground(output.Color("6")), + ) +} + +func ParseDryRunOutput(nixOutput string, verbose bool) { + parts := strings.Split("\n" + nixOutput, "\nthese") + + if len(parts) != 3 { + log.Println("no changes...") + log.Println("or I failed to parse it into the expected number of parts") + fmt.Println(parts) + return + } + toBuild := parsePackages(parts[1], "packages to build") + toFetch := parsePackages(parts[2], "packages to fetch") + + toBuild.show(verbose) + toFetch.show(verbose) +} + +func nixSpinner(host string) *spinner.Spinner { + msg := fmt.Sprintf("%s %s", " evaluating derivation for:", + output.String(host).Bold().Foreground(output.Color("6")), + ) + s := spinner.New( + spinner.CharSets[14], + 100*time.Millisecond, + spinner.WithSuffix(msg), + spinner.WithColor("fgHiMagenta"), + ) + s.Start() + return s +} + +func (o *Oizys) NixDryRun(verbose bool, rest ...string) { + args := []string{ + "build", o.Output(), "--dry-run", + } + args = append(args, rest...) + cmd := exec.Command("nix", args...) + s := nixSpinner(o.host) + result, err := cmd.CombinedOutput() + s.Stop() + if err != nil { + fmt.Println(string(result)) + log.Fatal(err) + } + ParseDryRunOutput(string(result), verbose) +} + +func (o *Oizys) NixosRebuild(subcmd string, rest ...string) { + args := []string{ + "nixos-rebuild", + subcmd, + "--flake", + o.flake, + } + args = append(args, rest...) + cmd := exec.Command("sudo", args...) + runCommand(cmd) +} + +func runCommand(cmd *exec.Cmd) { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + log.Fatal(err) + } +} + +func (o *Oizys) NixBuild(rest ...string) { + args := []string{"build", o.Output()} + args = append(args, rest...) + cmd := exec.Command("nix", args...) + runCommand(cmd) +} + +func (o *Oizys) CacheBuild(rest ...string) { + args := []string{ + "watch-exec", o.cache, "--", "nix", + "build", o.Output(), "--print-build-logs", + "--accept-flake-config", + } + args = append(args, rest...) + cmd := exec.Command("cachix", args...) + runCommand(cmd) +} + +func CheckFlake(flake string) { + if _, err := os.Stat(flake); errors.Is(err, fs.ErrNotExist) { + log.Fatalln("path to flake:", flake, "does not exist") + } +} + +func (o *Oizys) CheckFlake() { + if _, err := os.Stat(o.flake); errors.Is(err, fs.ErrNotExist) { + log.Fatalln("path to flake:", o.flake, "does not exist") + } +} + +func Output(flake string, host string) string { + return fmt.Sprintf( + "%s#nixosConfigurations.%s.config.system.build.toplevel", + flake, + host, + ) +} diff --git a/pkgs/oizys/oizys-go/pkg/oizys/oizys.go b/pkgs/oizys/oizys-go/pkg/oizys/oizys.go deleted file mode 100644 index f210303..0000000 --- a/pkgs/oizys/oizys-go/pkg/oizys/oizys.go +++ /dev/null @@ -1,145 +0,0 @@ -package oizys - -import ( - "errors" - "fmt" - "io/fs" - "log" - "os" - "os/exec" - "strings" - - "github.com/charmbracelet/bubbles/table" - "github.com/muesli/termenv" - "golang.org/x/term" - - "github.com/briandowns/spinner" - "time" -) - -func TerminalSize() (int, int) { - fd := os.Stdout.Fd() - if !term.IsTerminal(int(fd)) { - log.Fatal("failed to get terminal size") - } - w, h, err := term.GetSize(int(fd)) - if err != nil { - log.Fatal(err) - } - return w, h -} - -func ParseDryRunOutput(nixOutput string, verbose bool) { - output := termenv.NewOutput(os.Stdout) - parts := strings.Split(nixOutput, "\nthese") - if len(parts) != 3 { - log.Println("no changes...") - log.Println(output) - return - } - built := strings.Split(strings.TrimSpace(parts[1]), "\n")[1:] - fetched := strings.Split(strings.TrimSpace(parts[2]), "\n")[1:] - - fmt.Println("Packages to build:", - output.String(fmt.Sprint(len(built))).Bold().Foreground(output.Color("6")), - ) - var rows []table.Row - for _, pkg := range built { - s := strings.SplitN(pkg, "-", 2) - hash, name := strings.Replace(s[0], "/nix/store/", "", 1), s[1] - rows = append(rows, table.Row{hash, name}) - } - - fmt.Println("Packages to fetch:", - output.String(fmt.Sprint(len(fetched))).Bold().Foreground(output.Color("6")), - ) - for _, pkg := range fetched { - s := strings.SplitN(pkg, "-", 2) - hash, name := strings.Replace(s[0], "/nix/store/", "", 1), s[1] - rows = append(rows, table.Row{hash, name}) - } - - if verbose { - - w, _ := TerminalSize() - columns := []table.Column{ - {Title: "hash", Width: 34}, - {Title: "pkg", Width: int(w / 4)}, - } - ShowTable(columns, rows) - } -} - -func NixDryRun(flake string, host string, verbose bool) { - output := termenv.NewOutput(os.Stdout) - path := Output(flake, host) - cmd := exec.Command("nix", "build", path, "--dry-run") - s := spinner.New( - spinner.CharSets[14], - 100*time.Millisecond, - spinner.WithSuffix( - fmt.Sprintf("%s %s", " evaluating derivation for:", - output.String(host).Bold().Foreground(output.Color("6")), - )), - spinner.WithColor("fgHiMagenta")) - s.Start() - result, err := cmd.CombinedOutput() - s.Stop() - if err != nil { - fmt.Println(string(result)) - log.Fatal(err) - } - ParseDryRunOutput(string(result), verbose) -} - -func NixosRebuild(subcmd string, flake string, rest ...string) { - args := []string{ - "nixos-rebuild", - subcmd, - "--flake", - flake, - } - args = append(args, rest...) - cmd := exec.Command("sudo", args...) - runCommand(cmd) -} - -func runCommand(cmd *exec.Cmd) { - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - if err := cmd.Run(); err != nil { - log.Fatal(err) - } -} - -func NixBuild(path string, rest ...string) { - args := []string{"build", path} - args = append(args, rest...) - cmd := exec.Command("nix", args...) - runCommand(cmd) -} - -func CacheBuild(path string, cache string, rest ...string) { - args := []string{ - "watch-exec", cache, "--", "nix", - "build", path, "--print-build-logs", - "--accept-flake-config", - } - args = append(args, rest...) - cmd := exec.Command("cachix", args...) - runCommand(cmd) -} - -func CheckFlake(flake string) { - if _, err := os.Stat(flake); errors.Is(err, fs.ErrNotExist) { - log.Fatalln("path to flake:", flake, "does not exist") - } -} - -func Output(flake string, host string) string { - return fmt.Sprintf( - "%s#nixosConfigurations.%s.config.system.build.toplevel", - flake, - host, - ) -} diff --git a/pkgs/oizys/oizys-go/pkg/oizys/table.go b/pkgs/oizys/oizys-go/pkg/oizys/table.go deleted file mode 100644 index 014f09a..0000000 --- a/pkgs/oizys/oizys-go/pkg/oizys/table.go +++ /dev/null @@ -1,75 +0,0 @@ -package oizys - -import ( - "fmt" - "os" - - "github.com/charmbracelet/bubbles/table" - tea "github.com/charmbracelet/bubbletea" - "github.com/charmbracelet/lipgloss" -) - -var baseStyle = lipgloss.NewStyle(). - BorderStyle(lipgloss.NormalBorder()). - BorderForeground(lipgloss.Color("240")) - -type model struct { - table table.Model -} - -func (m model) Init() tea.Cmd { return nil } - -func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - var cmd tea.Cmd - switch msg := msg.(type) { - case tea.KeyMsg: - switch msg.String() { - case "esc": - if m.table.Focused() { - m.table.Blur() - } else { - m.table.Focus() - } - case "q", "ctrl+c": - return m, tea.Quit - case "enter": - return m, tea.Batch( - tea.Printf("Let's go to %s!", m.table.SelectedRow()[1]), - ) - } - } - m.table, cmd = m.table.Update(msg) - return m, cmd -} - -func (m model) View() string { - return baseStyle.Render(m.table.View()) + "\n" -} - -func ShowTable(columns []table.Column, rows []table.Row) { - - t := table.New( - table.WithColumns(columns), - table.WithRows(rows), - table.WithFocused(true), - table.WithHeight(15), - ) - - s := table.DefaultStyles() - s.Header = s.Header. - BorderStyle(lipgloss.NormalBorder()). - BorderForeground(lipgloss.Color("240")). - BorderBottom(true). - Bold(false) - s.Selected = s.Selected. - Foreground(lipgloss.Color("229")). - Background(lipgloss.Color("57")). - Bold(false) - t.SetStyles(s) - - m := model{t} - if _, err := tea.NewProgram(m).Run(); err != nil { - fmt.Println("Error running program:", err) - os.Exit(1) - } -}