mirror of
https://github.com/daylinmorgan/oizys.git
synced 2024-12-22 10:10:45 -06:00
remove oizys only nim remains
This commit is contained in:
parent
c05d695225
commit
3fc958cf2b
38 changed files with 19 additions and 1429 deletions
|
@ -41,9 +41,8 @@ let
|
||||||
packages = forAllSystems (
|
packages = forAllSystems (
|
||||||
pkgs:
|
pkgs:
|
||||||
rec {
|
rec {
|
||||||
default = oizys-nim;
|
default = oizys;
|
||||||
oizys-nim = pkgs.callPackage ../pkgs/oizys-nim { };
|
oizys = pkgs.callPackage ../pkgs/oizys { };
|
||||||
oizys-go = pkgs.callPackage ../pkgs/oizys { };
|
|
||||||
# nimlangserver = pkgs.callPackage ../pkgs/nimlangserver { };
|
# nimlangserver = pkgs.callPackage ../pkgs/nimlangserver { };
|
||||||
nph = pkgs.callPackage ../pkgs/nph { };
|
nph = pkgs.callPackage ../pkgs/nph { };
|
||||||
iso = mkIso.config.system.build.isoImage;
|
iso = mkIso.config.system.build.isoImage;
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
use flake "../..#oizys"
|
|
9
pkgs/oizys-nim/.gitignore
vendored
9
pkgs/oizys-nim/.gitignore
vendored
|
@ -1,9 +0,0 @@
|
||||||
nimbledeps
|
|
||||||
nimble.paths
|
|
||||||
nimble.develop
|
|
||||||
|
|
||||||
# binaries
|
|
||||||
oizys*
|
|
||||||
!src/oizys
|
|
||||||
!src/oizys.nim*
|
|
||||||
oizys.out
|
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
lib,
|
|
||||||
openssl,
|
|
||||||
buildNimblePackage,
|
|
||||||
}:
|
|
||||||
buildNimblePackage {
|
|
||||||
name = "oizys";
|
|
||||||
verions = "unstable";
|
|
||||||
src = lib.cleanSource ./.;
|
|
||||||
nativeBuildInputs = [ openssl ];
|
|
||||||
nimbleDepsHash = "sha256-RceRnhEkei3RfSCTOJsIiw4GSCyhOZhKoEVHNSw/KvA=";
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
# Package
|
|
||||||
|
|
||||||
version = "0.1.0"
|
|
||||||
author = "Daylin Morgan"
|
|
||||||
description = "nix begat oizys"
|
|
||||||
license = "MIT"
|
|
||||||
srcDir = "src"
|
|
||||||
bin = @["oizys"]
|
|
||||||
|
|
||||||
|
|
||||||
# Dependencies
|
|
||||||
|
|
||||||
requires "nim >= 2.0.8"
|
|
||||||
requires "cligen"
|
|
||||||
requires "jsony"
|
|
||||||
requires "zippy"
|
|
||||||
requires "https://github.com/daylinmorgan/hwylterm#HEAD"
|
|
||||||
|
|
9
pkgs/oizys/.gitignore
vendored
9
pkgs/oizys/.gitignore
vendored
|
@ -0,0 +1,9 @@
|
||||||
|
nimbledeps
|
||||||
|
nimble.paths
|
||||||
|
nimble.develop
|
||||||
|
|
||||||
|
# binaries
|
||||||
|
oizys*
|
||||||
|
!src/oizys
|
||||||
|
!src/oizys.nim*
|
||||||
|
oizys.out
|
|
@ -1,20 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"oizys/internal/oizys"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
var buildCmd = &cobra.Command{
|
|
||||||
Use: "build",
|
|
||||||
Short: "nix build",
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
oizys.NixBuild(minimal, args...)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(buildCmd)
|
|
||||||
buildCmd.Flags().BoolVar(&minimal, "minimal", false, "use system dry-run to make build args")
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"oizys/internal/oizys"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
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,
|
|
||||||
"cache",
|
|
||||||
"c",
|
|
||||||
"daylin",
|
|
||||||
"name of cachix binary cache",
|
|
||||||
)
|
|
||||||
rootCmd.AddCommand(cacheCmd)
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"oizys/internal/oizys"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
var checksCmd = &cobra.Command{
|
|
||||||
Use: "checks",
|
|
||||||
Short: "nix build checks",
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
oizys.Checks(args...)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(checksCmd)
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"oizys/internal/github"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/log"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
// gh workflow run build.yml -F lockFile=@flake.lock
|
|
||||||
|
|
||||||
var ciCmd = &cobra.Command{
|
|
||||||
Use: "ci",
|
|
||||||
Short: "offload build to GHA",
|
|
||||||
Args: cobra.ExactArgs(1),
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
inputs := make(map[string]interface{})
|
|
||||||
if includeLock {
|
|
||||||
log.Debug("including lock file in inputs")
|
|
||||||
inputs["lockFile"] = readLockFile()
|
|
||||||
}
|
|
||||||
github.CreateDispatch(args[0], ref, inputs)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var includeLock bool
|
|
||||||
var ref string
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(ciCmd)
|
|
||||||
ciCmd.Flags().BoolVar(&includeLock, "lockfile", false, "include lock file in inputs")
|
|
||||||
ciCmd.Flags().StringVar(&ref, "ref", "main", "git ref to trigger workflow on")
|
|
||||||
}
|
|
||||||
|
|
||||||
func readLockFile() string {
|
|
||||||
dat, err := os.ReadFile("flake.lock")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("failed to read flake.lock", "err", err)
|
|
||||||
}
|
|
||||||
return string(dat)
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"oizys/internal/oizys"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
var dryCmd = &cobra.Command{
|
|
||||||
Use: "dry",
|
|
||||||
Short: "poor man's nix flake check",
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
oizys.Dry(minimal, args...)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(dryCmd)
|
|
||||||
dryCmd.Flags().BoolVarP(&minimal, "minimal", "m", false, "use system dry-run to make build args")
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"oizys/internal/oizys"
|
|
||||||
"slices"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
var validArgs = []string{
|
|
||||||
"switch", "boot", "test", "build", "dry-build",
|
|
||||||
"dry-activate", "edit", "repl",
|
|
||||||
"build-vm", "build-vm-with-bootloader",
|
|
||||||
"list-generations",
|
|
||||||
}
|
|
||||||
|
|
||||||
var osCmd = &cobra.Command{
|
|
||||||
Use: "os [subcmd]",
|
|
||||||
Short: "nixos-rebuild wrapper",
|
|
||||||
Args: func(cmd *cobra.Command, args []string) error {
|
|
||||||
if err := cobra.MinimumNArgs(1)(cmd, args); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if slices.Contains(validArgs, args[0]) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return fmt.Errorf(
|
|
||||||
"unexpected arg: %s\nexpected one of:\n %s",
|
|
||||||
args[0],
|
|
||||||
strings.Join(validArgs, ", "),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
subcmd := args[0]
|
|
||||||
oizys.NixosRebuild(subcmd, args[1:]...)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(osCmd)
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"oizys/internal/oizys"
|
|
||||||
)
|
|
||||||
|
|
||||||
var outputCmd = &cobra.Command{
|
|
||||||
Use: "output",
|
|
||||||
Short: "show nixosConfiguration attr",
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
oizys.Output()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(outputCmd)
|
|
||||||
outputCmd.Flags().BoolVar(&systemPath, "system-path", false, "show system-path drv")
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"oizys/internal/oizys"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
|
||||||
"github.com/charmbracelet/log"
|
|
||||||
cc "github.com/ivanpirog/coloredcobra"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Execute() {
|
|
||||||
cc.Init(&cc.Config{
|
|
||||||
RootCmd: rootCmd,
|
|
||||||
Headings: cc.HiMagenta + cc.Bold,
|
|
||||||
Commands: cc.Bold,
|
|
||||||
Example: cc.Italic,
|
|
||||||
ExecName: cc.Bold,
|
|
||||||
Flags: cc.Bold,
|
|
||||||
NoExtraNewlines: true,
|
|
||||||
NoBottomNewline: true,
|
|
||||||
})
|
|
||||||
err := rootCmd.Execute()
|
|
||||||
if err != nil {
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
flake string
|
|
||||||
host string
|
|
||||||
debug bool
|
|
||||||
systemPath bool
|
|
||||||
resetCache bool
|
|
||||||
minimal bool
|
|
||||||
)
|
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
|
||||||
Use: "oizys",
|
|
||||||
Short: "nix begat oizys",
|
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
|
||||||
if debug {
|
|
||||||
log.Info("running in debug mode")
|
|
||||||
log.SetLevel(log.DebugLevel)
|
|
||||||
}
|
|
||||||
oizys.SetFlake(flake)
|
|
||||||
oizys.SetHost(host)
|
|
||||||
oizys.SetResetCache(resetCache)
|
|
||||||
oizys.SetDebug(debug)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupLogger() {
|
|
||||||
log.SetReportTimestamp(false)
|
|
||||||
styles := log.DefaultStyles()
|
|
||||||
colors := map[log.Level]string{
|
|
||||||
log.DebugLevel: "8",
|
|
||||||
log.InfoLevel: "6",
|
|
||||||
log.WarnLevel: "3",
|
|
||||||
log.ErrorLevel: "1",
|
|
||||||
log.FatalLevel: "1",
|
|
||||||
}
|
|
||||||
for k, v := range colors {
|
|
||||||
styles.Levels[k] = styles.Levels[k].MaxWidth(5).Width(5).Foreground(lipgloss.Color(v))
|
|
||||||
}
|
|
||||||
log.SetStyles(styles)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
setupLogger()
|
|
||||||
|
|
||||||
rootCmd.CompletionOptions.HiddenDefaultCmd = true
|
|
||||||
rootCmd.PersistentFlags().StringVar(&flake, "flake", "", "path to flake ($OIZYS_DIR or $HOME/oizys)")
|
|
||||||
rootCmd.PersistentFlags().StringVar(&host, "host", "", "host(s) to build (current host)")
|
|
||||||
rootCmd.PersistentFlags().BoolVar(&debug, "debug", false, "show debug output")
|
|
||||||
rootCmd.PersistentFlags().BoolVar(&resetCache, "reset-cache", false, "set narinfo-cache-negative-ttl to 0")
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"oizys/internal/github"
|
|
||||||
"oizys/internal/oizys"
|
|
||||||
"oizys/internal/ui"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/log"
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
var updateCmd = &cobra.Command{
|
|
||||||
Use: "update",
|
|
||||||
Short: "update and run nixos rebuild",
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
run := github.GetLastUpdateRun()
|
|
||||||
md, err := github.GetUpateSummary(run.GetID(), oizys.GetHost())
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
fmt.Println(md)
|
|
||||||
if preview {
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
if !yes && !ui.Confirm("proceed with system update?") {
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
oizys.UpdateRepo()
|
|
||||||
oizys.NixosRebuild("switch")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
preview bool
|
|
||||||
yes bool
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(updateCmd)
|
|
||||||
updateCmd.Flags().BoolVar(&preview, "preview", false, "confirm nix store diff")
|
|
||||||
updateCmd.Flags().BoolVar(&yes, "yes", false, "reply yes to all confirm prompts")
|
|
||||||
}
|
|
|
@ -1,29 +1,15 @@
|
||||||
{
|
{
|
||||||
lib,
|
lib,
|
||||||
installShellFiles,
|
openssl,
|
||||||
buildGoModule,
|
buildNimblePackage,
|
||||||
makeWrapper,
|
|
||||||
...
|
|
||||||
}:
|
}:
|
||||||
let
|
buildNimblePackage {
|
||||||
inherit (lib) cleanSource;
|
name = "oizys";
|
||||||
in
|
verions = "unstable";
|
||||||
buildGoModule {
|
src = lib.cleanSource ./.;
|
||||||
pname = "oizys";
|
nativeBuildInputs = [ openssl ];
|
||||||
version = "unstable";
|
nimbleDepsHash = "sha256-RceRnhEkei3RfSCTOJsIiw4GSCyhOZhKoEVHNSw/KvA=";
|
||||||
|
|
||||||
src = cleanSource ./.;
|
|
||||||
vendorHash = "sha256-+4OtpcKHfomBAXRrJOvkhQdCSwU0W6+5OJuS4o12r5E=";
|
|
||||||
|
|
||||||
nativeBuildInputs = [
|
|
||||||
installShellFiles
|
|
||||||
makeWrapper
|
|
||||||
];
|
|
||||||
|
|
||||||
postInstall = ''
|
|
||||||
installShellCompletion --cmd oizys \
|
|
||||||
--zsh <(OIZYS_SKIP_CHECK=true $out/bin/oizys completion zsh)
|
|
||||||
'';
|
|
||||||
meta = {
|
meta = {
|
||||||
description = "nix begat oizys";
|
description = "nix begat oizys";
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
module oizys
|
|
||||||
|
|
||||||
go 1.22.2
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/briandowns/spinner v1.23.0
|
|
||||||
github.com/charmbracelet/lipgloss v0.11.0
|
|
||||||
github.com/charmbracelet/log v0.4.0
|
|
||||||
github.com/google/go-github/v63 v63.0.0
|
|
||||||
github.com/ivanpirog/coloredcobra v1.0.1
|
|
||||||
github.com/spf13/cobra v1.8.0
|
|
||||||
)
|
|
||||||
|
|
||||||
require (
|
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
|
||||||
github.com/charmbracelet/x/ansi v0.1.2 // indirect
|
|
||||||
github.com/fatih/color v1.17.0 // indirect
|
|
||||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
|
||||||
github.com/google/go-querystring v1.1.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-runewidth v0.0.15 // 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/exp v0.0.0-20231006140011-7918f672742d // indirect
|
|
||||||
golang.org/x/sys v0.21.0 // indirect
|
|
||||||
golang.org/x/term v0.21.0 // indirect
|
|
||||||
)
|
|
|
@ -1,74 +0,0 @@
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
|
||||||
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/lipgloss v0.11.0 h1:UoAcbQ6Qml8hDwSWs0Y1cB5TEQuZkDPH/ZqwWWYTG4g=
|
|
||||||
github.com/charmbracelet/lipgloss v0.11.0/go.mod h1:1UdRTH9gYgpcdNN5oBtjbu/IzNKtzVtb7sqN1t9LNn8=
|
|
||||||
github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM=
|
|
||||||
github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM=
|
|
||||||
github.com/charmbracelet/x/ansi v0.1.2 h1:6+LR39uG8DE6zAmbu023YlqjJHkYXDF1z36ZwzO4xZY=
|
|
||||||
github.com/charmbracelet/x/ansi v0.1.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
|
||||||
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/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
||||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
|
||||||
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
|
|
||||||
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
|
|
||||||
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
|
||||||
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
|
||||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
|
||||||
github.com/google/go-github/v63 v63.0.0 h1:13xwK/wk9alSokujB9lJkuzdmQuVn2QCPeck76wR3nE=
|
|
||||||
github.com/google/go-github/v63 v63.0.0/go.mod h1:IqbcrgUmIcEaioWrGYei/09o+ge5vhffGOcxrO0AfmA=
|
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
|
||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
|
||||||
github.com/ivanpirog/coloredcobra v1.0.1 h1:aURSdEmlR90/tSiWS0dMjdwOvCVUeYLfltLfbgNxrN4=
|
|
||||||
github.com/ivanpirog/coloredcobra v1.0.1/go.mod h1:iho4nEKcnwZFiniGSdcgdvRgZNjxm+h20acv8vqmN6Q=
|
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
|
||||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
|
||||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
|
||||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
|
||||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
|
||||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
|
||||||
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-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
|
||||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
|
||||||
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
|
||||||
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
|
||||||
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=
|
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
|
||||||
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
|
|
||||||
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=
|
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
|
||||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
|
||||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
|
||||||
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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
|
||||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
|
||||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
|
||||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
|
@ -1,48 +0,0 @@
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,65 +0,0 @@
|
||||||
package git
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"oizys/internal/ui"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GitRepo struct {
|
|
||||||
path string
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRepo(path string) *GitRepo {
|
|
||||||
repo := new(GitRepo)
|
|
||||||
repo.path = path
|
|
||||||
return repo
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GitRepo) git(rest ...string) *exec.Cmd {
|
|
||||||
args := []string{"-C", g.path}
|
|
||||||
args = append(args, rest...)
|
|
||||||
cmd := exec.Command("git", args...)
|
|
||||||
// logCmd(cmd)
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GitRepo) Fetch() {
|
|
||||||
err := g.git("fetch").Run()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GitRepo) Rebase(ref string) {
|
|
||||||
g.Status()
|
|
||||||
err := g.git("rebase", ref).Run()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GitRepo) Status() {
|
|
||||||
cmdOutput, err := g.git("status", "--porcelain").Output()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cmdOutput) > 0 {
|
|
||||||
fmt.Println("unstaged commits, cowardly exiting...")
|
|
||||||
ui.ShowFailedOutput(cmdOutput)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *GitRepo) Pull() {
|
|
||||||
g.Status()
|
|
||||||
cmdOutput, err := g.git("pull").CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
ui.ShowFailedOutput(cmdOutput)
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,174 +0,0 @@
|
||||||
package github
|
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/zip"
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"oizys/internal/oizys"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/log"
|
|
||||||
"github.com/google/go-github/v63/github"
|
|
||||||
)
|
|
||||||
|
|
||||||
var client *github.Client
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
client = github.NewClient(nil).WithAuthToken(oizys.GithubToken())
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListWorkflows() {
|
|
||||||
workflowRuns, resp, err := client.Actions.ListWorkflowRunsByFileName(
|
|
||||||
context.Background(),
|
|
||||||
"daylinmorgan",
|
|
||||||
"oizys",
|
|
||||||
"update.yml",
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Failed to get a list of workflows", "err", err, "resp", resp)
|
|
||||||
}
|
|
||||||
for _, w := range workflowRuns.WorkflowRuns {
|
|
||||||
fmt.Println(w.GetID())
|
|
||||||
fmt.Println(w.GetConclusion())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ListUpdateRuns() (*github.WorkflowRuns, *github.Response) {
|
|
||||||
workflowRuns, resp, err := client.Actions.ListWorkflowRunsByFileName(
|
|
||||||
context.Background(),
|
|
||||||
"daylinmorgan",
|
|
||||||
"oizys",
|
|
||||||
"update.yml",
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("failed to get last update run", "resp", resp, "err", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return workflowRuns, resp
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetArtifacts(runID int64) (*github.ArtifactList, *github.Response) {
|
|
||||||
artifactList, resp, err := client.Actions.ListWorkflowRunArtifacts(context.Background(), "daylinmorgan", "oizys", runID, nil)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("failed to get artifacts for run", "id", runID, "err", err)
|
|
||||||
}
|
|
||||||
return artifactList, resp
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetUpdateSummaryArtifact(runID int64, host string) *github.Artifact {
|
|
||||||
artifactName := fmt.Sprintf("%s-summary", host)
|
|
||||||
artifactList, _ := GetArtifacts(runID)
|
|
||||||
for _, artifact := range artifactList.Artifacts {
|
|
||||||
if artifact.GetName() == artifactName {
|
|
||||||
return artifact
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Fatal("failed to find summary for run", "id", runID)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetUpdateSummaryUrl(runID int64, host string) *url.URL {
|
|
||||||
artifact := GetUpdateSummaryArtifact(runID, host)
|
|
||||||
url, resp, err := client.Actions.DownloadArtifact(context.Background(), "daylinmorgan", "oizys", artifact.GetID(), 4)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("failed to get update summary URL", "artifact", artifact.GetID(), "resp", resp)
|
|
||||||
}
|
|
||||||
return url
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetUpdateSummaryFromUrl(url *url.URL) []byte {
|
|
||||||
log.Debug(url.String())
|
|
||||||
res, err := http.Get(url.String())
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("failed to get update summary zip", "err", err)
|
|
||||||
}
|
|
||||||
body, err := io.ReadAll(res.Body)
|
|
||||||
res.Body.Close()
|
|
||||||
if res.StatusCode > 299 {
|
|
||||||
log.Fatalf("Response failed with status code: %d and\nbody: %s\n", res.StatusCode, body)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
return body
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetLastUpdateRun() *github.WorkflowRun {
|
|
||||||
workflowRuns, _ := ListUpdateRuns()
|
|
||||||
run := workflowRuns.WorkflowRuns[0]
|
|
||||||
if run.GetConclusion() == "failure" {
|
|
||||||
log.Fatal("Most recent run was not successful", "runId", run.GetID(), "conclusion", run.GetConclusion())
|
|
||||||
}
|
|
||||||
if run.GetStatus() == "in_progress" {
|
|
||||||
log.Fatalf("Most recent run is not finished\nview workflow run at: %s", run.GetHTMLURL())
|
|
||||||
}
|
|
||||||
return run
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetUpateSummary(runID int64, host string) (string, error) {
|
|
||||||
url := GetUpdateSummaryUrl(runID, host)
|
|
||||||
bytes := GetUpdateSummaryFromUrl(url)
|
|
||||||
md, err := ReadMarkdownFromZip(bytes, "summary.md")
|
|
||||||
return md, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func ReadMarkdownFromZip(zipData []byte, fileName string) (string, error) {
|
|
||||||
// Open the zip reader from the in-memory byte slice
|
|
||||||
reader, err := zip.NewReader(bytes.NewReader(zipData), int64(len(zipData)))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search for the target file
|
|
||||||
var markdownFile *zip.File
|
|
||||||
for _, f := range reader.File {
|
|
||||||
if f.Name == fileName {
|
|
||||||
markdownFile = f
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if markdownFile == nil {
|
|
||||||
return "", fmt.Errorf("file %s not found in zip archive", fileName)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open the markdown file reader
|
|
||||||
fileReader, err := markdownFile.Open()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
defer fileReader.Close()
|
|
||||||
|
|
||||||
// Read the markdown content
|
|
||||||
content, err := io.ReadAll(fileReader)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the markdown content as string
|
|
||||||
return string(content), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateDispatch(workflowFileName string, ref string, inputs map[string]interface{}) {
|
|
||||||
if !strings.HasSuffix(workflowFileName, ".yml") && !strings.HasSuffix(workflowFileName, ".yaml") {
|
|
||||||
workflowFileName = workflowFileName + ".yml"
|
|
||||||
}
|
|
||||||
log.Infof("creating dispatch event for %s", workflowFileName)
|
|
||||||
event := github.CreateWorkflowDispatchEventRequest{Ref: ref, Inputs: inputs}
|
|
||||||
_, err := client.Actions.CreateWorkflowDispatchEventByFileName(
|
|
||||||
context.Background(),
|
|
||||||
"daylinmorgan",
|
|
||||||
"oizys",
|
|
||||||
workflowFileName,
|
|
||||||
event,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("failed to dispatch event", "filename", workflowFileName, "err", err)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
ld-library-path
|
|
||||||
builder.pl
|
|
||||||
profile
|
|
||||||
system-path
|
|
||||||
nixos-help
|
|
||||||
nixos-install
|
|
||||||
nixos-version
|
|
||||||
nixos-manual-html
|
|
||||||
nixos-rebuild
|
|
||||||
nixos-configuration-reference-manpage
|
|
||||||
nixos-generate-config
|
|
||||||
nixos-enter
|
|
||||||
nixos-container
|
|
||||||
nixos-build-vms
|
|
||||||
nixos-wsl-version
|
|
||||||
nixos-wsl-welcome-message
|
|
||||||
nixos-wsl-welcome
|
|
||||||
restic-gdrive
|
|
||||||
gitea
|
|
||||||
lock
|
|
||||||
code
|
|
|
@ -1,354 +0,0 @@
|
||||||
package oizys
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io/fs"
|
|
||||||
"oizys/internal/git"
|
|
||||||
|
|
||||||
// "oizys/internal/github"
|
|
||||||
"oizys/internal/ui"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
|
||||||
"github.com/charmbracelet/log"
|
|
||||||
|
|
||||||
e "oizys/internal/exec"
|
|
||||||
)
|
|
||||||
|
|
||||||
var o *Oizys
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
o = New()
|
|
||||||
}
|
|
||||||
|
|
||||||
// verbose vs debug?
|
|
||||||
type Oizys struct {
|
|
||||||
repo *git.GitRepo
|
|
||||||
flake string
|
|
||||||
host string
|
|
||||||
cache string
|
|
||||||
githubSummary string
|
|
||||||
githubToken string
|
|
||||||
local bool
|
|
||||||
inCI bool
|
|
||||||
systemPath bool
|
|
||||||
resetCache bool
|
|
||||||
debug bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func New() *Oizys {
|
|
||||||
o := new(Oizys)
|
|
||||||
o.cache = "daylin"
|
|
||||||
hostname, err := os.Hostname()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("failed to determine hostname", "err", err)
|
|
||||||
}
|
|
||||||
o.host = hostname
|
|
||||||
oizysDir, ok := os.LookupEnv("OIZYS_DIR")
|
|
||||||
if !ok {
|
|
||||||
home := os.Getenv("HOME")
|
|
||||||
o.flake = fmt.Sprintf("%s/%s", home, "oizys")
|
|
||||||
} else {
|
|
||||||
o.flake = oizysDir
|
|
||||||
}
|
|
||||||
o.githubSummary = os.Getenv("GITHUB_STEP_SUMMARY")
|
|
||||||
if o.githubSummary != "" {
|
|
||||||
o.inCI = true
|
|
||||||
log.Debug("running oizys in CI mode")
|
|
||||||
}
|
|
||||||
o.githubToken = os.Getenv("GITHUB_TOKEN")
|
|
||||||
o.repo = git.NewRepo(o.flake)
|
|
||||||
return o
|
|
||||||
}
|
|
||||||
|
|
||||||
func GithubToken() string {
|
|
||||||
return o.githubToken
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetFlake(path string) {
|
|
||||||
// Check path exists
|
|
||||||
if path != "" {
|
|
||||||
o.flake = path
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if path is local and exists
|
|
||||||
if !strings.HasPrefix(o.flake, "github") && !strings.HasPrefix(o.flake, "git+") {
|
|
||||||
if _, ok := os.LookupEnv("OIZYS_SKIP_CHECK"); !ok {
|
|
||||||
if _, err := os.Stat(o.flake); errors.Is(err, fs.ErrNotExist) {
|
|
||||||
log.Warnf("path to flake %s does not exist, using remote as fallback", o.flake)
|
|
||||||
o.flake = "github:daylinmorgan/oizys"
|
|
||||||
} else {
|
|
||||||
o.local = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetDebug(debug bool) { o.debug = debug }
|
|
||||||
|
|
||||||
func SetCache(name string) {
|
|
||||||
if name != "" {
|
|
||||||
o.cache = name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetHost(name string) {
|
|
||||||
if name != "" {
|
|
||||||
o.host = name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetHost() string { return o.host }
|
|
||||||
|
|
||||||
func SetResetCache(reset bool) {
|
|
||||||
o.resetCache = reset
|
|
||||||
}
|
|
||||||
|
|
||||||
func NixosConfigAttrs() (attrs []string) {
|
|
||||||
for _, host := range strings.Split(o.host, " ") {
|
|
||||||
attrs = append(attrs, o.nixosConfigAttr(host))
|
|
||||||
}
|
|
||||||
return attrs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Oizys) nixosConfigAttr(host string) string {
|
|
||||||
return fmt.Sprintf(
|
|
||||||
"%s#nixosConfigurations.%s.config.system.build.toplevel",
|
|
||||||
o.flake,
|
|
||||||
host,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Output() {
|
|
||||||
if o.systemPath {
|
|
||||||
drv := evaluateDerivations(NixosConfigAttrs()...)
|
|
||||||
systemPaths, err := findSystemPaths(drv)
|
|
||||||
// systemPath, err := findSystemPath(drv)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("error collecting system paths", "err", err)
|
|
||||||
}
|
|
||||||
for _, drv := range systemPaths {
|
|
||||||
fmt.Println(drv)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for _, drv := range NixosConfigAttrs() {
|
|
||||||
fmt.Println(drv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseDryRun(buf string) (*ui.Packages, *ui.Packages) {
|
|
||||||
lines := strings.Split(strings.TrimSpace(buf), "\n")
|
|
||||||
var parts [2][]string
|
|
||||||
i := 0
|
|
||||||
for _, line := range lines {
|
|
||||||
if strings.Contains(line, "fetch") && strings.HasSuffix(line, ":") {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if i == 2 {
|
|
||||||
log.Fatal("failed to parse output", "output", buf)
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(line, " ") {
|
|
||||||
parts[i] = append(parts[i], line)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(parts[0])+len(parts[1]) == 0 {
|
|
||||||
log.Info("no changes...")
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ui.ParsePackages(parts[0], "packages to build"),
|
|
||||||
ui.ParsePackages(parts[1], "packages to fetch")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Refactor this and above
|
|
||||||
func parseDryRun2(buf string) ([]string, []string) {
|
|
||||||
lines := strings.Split(strings.TrimSpace(buf), "\n")
|
|
||||||
var parts [2][]string
|
|
||||||
i := 0
|
|
||||||
for _, line := range lines {
|
|
||||||
if strings.Contains(line, "fetch") && strings.HasSuffix(line, ":") {
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
if i == 2 {
|
|
||||||
log.Fatal("failed to parse output", "output", buf)
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(line, " ") {
|
|
||||||
parts[i] = append(parts[i], strings.TrimSpace(line))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(parts[0])+len(parts[1]) == 0 {
|
|
||||||
log.Info("no changes...")
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
return parts[0], parts[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: refactor to account for --debug and not --verbose?
|
|
||||||
func showDryRunResult(nixOutput string) {
|
|
||||||
toBuild, toFetch := parseDryRun(nixOutput)
|
|
||||||
toFetch.Show(o.debug)
|
|
||||||
toBuild.Show(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Dry(minimal bool, rest ...string) {
|
|
||||||
cmd := exec.Command("nix", "build", "--dry-run")
|
|
||||||
cmd.Args = append(cmd.Args, rest...)
|
|
||||||
if o.resetCache {
|
|
||||||
cmd.Args = append(cmd.Args, "--narinfo-cache-negative-ttl", "0")
|
|
||||||
}
|
|
||||||
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, append(drvs, "--no-link")...)
|
|
||||||
spinnerMsg = "evaluting for minimal build needs"
|
|
||||||
} else {
|
|
||||||
log.Debug("evalutating full nixosConfiguration")
|
|
||||||
cmd.Args = append(cmd.Args, NixosConfigAttrs()...)
|
|
||||||
spinnerMsg = fmt.Sprintf("%s %s", "evaluating derivation for:",
|
|
||||||
lipgloss.NewStyle().Bold(true).Foreground(lipgloss.Color("6")).Render(o.host),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
result, err := e.CmdOutputWithSpinner(cmd, spinnerMsg, true)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("failed to dry-run nix build", "err", err, "output", string(result))
|
|
||||||
}
|
|
||||||
if minimal {
|
|
||||||
fmt.Println(string(result))
|
|
||||||
} else {
|
|
||||||
showDryRunResult(string(result))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup command completely differently here
|
|
||||||
func NixosRebuild(subcmd string, rest ...string) {
|
|
||||||
cmd := exec.Command("sudo",
|
|
||||||
"nixos-rebuild",
|
|
||||||
subcmd,
|
|
||||||
"--flake",
|
|
||||||
o.flake,
|
|
||||||
)
|
|
||||||
if !o.inCI {
|
|
||||||
cmd.Args = append(cmd.Args, "--log-format", "multiline")
|
|
||||||
}
|
|
||||||
if o.debug {
|
|
||||||
cmd.Args = append(cmd.Args, "--print-build-logs")
|
|
||||||
}
|
|
||||||
cmd.Args = append(cmd.Args, rest...)
|
|
||||||
e.ExitWithCommand(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
func splitDrv(drv string) (string, string) {
|
|
||||||
s := strings.SplitN(drv, "-", 2)
|
|
||||||
ss := strings.Split(s[0], "/")
|
|
||||||
hash := ss[len(ss)-1]
|
|
||||||
drvName := strings.Replace(s[1], ".drv^*", "", 1)
|
|
||||||
return drvName, hash
|
|
||||||
}
|
|
||||||
|
|
||||||
const tableTmpl = `# Building Derivations
|
|
||||||
| derivation | hash |
|
|
||||||
|---|---|
|
|
||||||
%s
|
|
||||||
`
|
|
||||||
|
|
||||||
func writeDervationsToStepSummary(drvs []string) {
|
|
||||||
tableRows := make([]string, len(drvs))
|
|
||||||
for i, drv := range drvs {
|
|
||||||
name, hash := splitDrv(drv)
|
|
||||||
tableRows[i] = fmt.Sprintf(
|
|
||||||
"| %s | %s |",
|
|
||||||
name, hash,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
o.writeToGithubStepSummary(fmt.Sprintf(tableTmpl, strings.Join(tableRows, "\n")))
|
|
||||||
}
|
|
||||||
|
|
||||||
func NixBuild(minimal bool, rest ...string) {
|
|
||||||
cmd := exec.Command("nix", "build")
|
|
||||||
if o.resetCache {
|
|
||||||
cmd.Args = append(cmd.Args, "--narinfo-cache-negative-ttl", "0")
|
|
||||||
}
|
|
||||||
if minimal {
|
|
||||||
log.Debug("populating args with derivations not already built")
|
|
||||||
drvs := systemPathDrvsToBuild()
|
|
||||||
if len(drvs) == 0 {
|
|
||||||
log.Info("nothing to build. exiting...")
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
if o.inCI {
|
|
||||||
writeDervationsToStepSummary(drvs)
|
|
||||||
}
|
|
||||||
cmd.Args = append(cmd.Args, append(drvs, "--no-link")...)
|
|
||||||
}
|
|
||||||
if !o.inCI {
|
|
||||||
cmd.Args = append(cmd.Args, "--log-format", "multiline")
|
|
||||||
}
|
|
||||||
cmd.Args = append(cmd.Args, rest...)
|
|
||||||
e.ExitWithCommand(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if _, err := f.Write([]byte(txt)); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
if err := f.Close(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Oizys) getChecks() []string {
|
|
||||||
attrName := fmt.Sprintf("%s#%s", o.flake, "checks.x86_64-linux")
|
|
||||||
cmd := exec.Command("nix", "eval", attrName, "--apply", "builtins.attrNames", "--json")
|
|
||||||
out, err := cmd.Output()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
var checks []string
|
|
||||||
if err := json.Unmarshal(out, &checks); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
return checks
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o *Oizys) checkPath(name string) string {
|
|
||||||
return fmt.Sprintf("%s#checks.x86_64-linux.%s", o.flake, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Checks(rest ...string) {
|
|
||||||
checks := o.getChecks()
|
|
||||||
for _, check := range checks {
|
|
||||||
NixBuild(false, o.checkPath(check))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func CacheBuild(rest ...string) {
|
|
||||||
args := []string{
|
|
||||||
"watch-exec", o.cache, "--", "nix",
|
|
||||||
"build", "--print-build-logs",
|
|
||||||
"--accept-flake-config",
|
|
||||||
}
|
|
||||||
args = append(args, NixosConfigAttrs()...)
|
|
||||||
args = append(args, rest...)
|
|
||||||
cmd := exec.Command("cachix", args...)
|
|
||||||
e.ExitWithCommand(cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
func UpdateRepo() {
|
|
||||||
log.Info("rebasing HEAD on origin/flake-lock")
|
|
||||||
o.repo.Fetch()
|
|
||||||
o.repo.Rebase("origin/flake-lock")
|
|
||||||
}
|
|
|
@ -1,186 +0,0 @@
|
||||||
package oizys
|
|
||||||
|
|
||||||
import (
|
|
||||||
_ "embed"
|
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"os/exec"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
e "oizys/internal/exec"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
//go:embed ignored.txt
|
|
||||||
var ignoredList string
|
|
||||||
var ignoredMap = stringToMap(ignoredList)
|
|
||||||
|
|
||||||
func stringToMap(s string) map[string]struct{} {
|
|
||||||
return stringSliceToMap(strings.Split(s, "\n"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func stringSliceToMap(slice []string) map[string]struct{} {
|
|
||||||
hashMap := make(map[string]struct{}, len(slice))
|
|
||||||
for _, s := range slice {
|
|
||||||
hashMap[s] = struct{}{}
|
|
||||||
}
|
|
||||||
return hashMap
|
|
||||||
}
|
|
||||||
|
|
||||||
type Derivation struct {
|
|
||||||
InputDrvs map[string]interface{}
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func findSystemPath(nixosDrv Derivation) (string, error) {
|
|
||||||
for drv := range nixosDrv.InputDrvs {
|
|
||||||
if strings.HasSuffix(drv, "system-path.drv") {
|
|
||||||
return drv, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", errors.New("failed to find path for system-path.drv")
|
|
||||||
}
|
|
||||||
|
|
||||||
func findSystemPaths(drv map[string]Derivation) ([]string, error) {
|
|
||||||
hosts := strings.Split(o.host, " ")
|
|
||||||
systemDrvs := make([]string, 0, len(hosts))
|
|
||||||
for _, p := range Keys(drv) {
|
|
||||||
if strings.HasPrefix(strings.SplitN(p, "-", 2)[1], "nixos-system-") {
|
|
||||||
systemDrvs = append(systemDrvs, p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(hosts) != len(systemDrvs) {
|
|
||||||
return nil, errors.New("didn't find appropriate number of nixos-system derivations")
|
|
||||||
}
|
|
||||||
systemPaths := make([]string, 0, len(hosts))
|
|
||||||
for _, name := range systemDrvs {
|
|
||||||
systemPath, err := findSystemPath(drv[name])
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("error finding system-path for %s: %w", name, err)
|
|
||||||
}
|
|
||||||
systemPaths = append(systemPaths, systemPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
return systemPaths, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func drvNotIgnored(drv string) bool {
|
|
||||||
s := strings.SplitN(strings.Replace(drv, ".drv", "", 1), "-", 2)
|
|
||||||
_, ok := ignoredMap[s[len(s)-1]]
|
|
||||||
return !ok
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func drvsToInputs(derivation map[string]Derivation) []string {
|
|
||||||
var drvs []string
|
|
||||||
for _, drv := range derivation {
|
|
||||||
for name := range drv.InputDrvs {
|
|
||||||
drvs = append(drvs, name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return drvs
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
|
|
||||||
func nixDerivationShowToInputs(output []byte) []string {
|
|
||||||
var derivation map[string]Derivation
|
|
||||||
if err := json.Unmarshal(output, &derivation); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
return drvsToInputs(derivation)
|
|
||||||
}
|
|
||||||
|
|
||||||
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", "--dry-run")
|
|
||||||
systemCmd.Args = append(systemCmd.Args, NixosConfigAttrs()...)
|
|
||||||
if o.resetCache {
|
|
||||||
systemCmd.Args = append(systemCmd.Args, "--narinfo-cache-negative-ttl", "0")
|
|
||||||
}
|
|
||||||
result, err := e.CmdOutputWithSpinner(
|
|
||||||
systemCmd,
|
|
||||||
fmt.Sprintf("running dry build for: %s", strings.Join(NixosConfigAttrs(), " ")),
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("failed to dry-run build system", "err", err)
|
|
||||||
}
|
|
||||||
toBuild, _ := parseDryRun2(string(result))
|
|
||||||
return toBuild
|
|
||||||
}
|
|
||||||
|
|
||||||
func evaluateDerivations(drvs ...string) map[string]Derivation {
|
|
||||||
cmd := exec.Command("nix", "derivation", "show", "-r")
|
|
||||||
cmd.Args = append(cmd.Args, drvs...)
|
|
||||||
out, err := e.CmdOutputWithSpinner(cmd,
|
|
||||||
fmt.Sprintf("evaluating derivations %s", strings.Join(drvs, " ")),
|
|
||||||
false)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("failed to evalute derivation for", "drvs", drvs, "err", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var derivation map[string]Derivation
|
|
||||||
if err := json.Unmarshal(out, &derivation); err != nil {
|
|
||||||
log.Fatal("failed to decode json", "err", err)
|
|
||||||
}
|
|
||||||
return derivation
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keys returns the keys of the map m.
|
|
||||||
// The keys will be an indeterminate order.
|
|
||||||
func Keys[M ~map[K]V, K comparable, V any](m M) []K {
|
|
||||||
r := make([]K, 0, len(m))
|
|
||||||
for k := range m {
|
|
||||||
r = append(r, k)
|
|
||||||
}
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func systemPathDrvsToBuild() []string {
|
|
||||||
toBuild := toBuildNixosConfiguration()
|
|
||||||
drv := evaluateDerivations(NixosConfigAttrs()...)
|
|
||||||
systemPaths, err := findSystemPaths(drv)
|
|
||||||
// systemPath, err := findSystemPath(drv)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("error collecting system paths", "err", err)
|
|
||||||
}
|
|
||||||
var inputDrvs []string
|
|
||||||
for _, path := range systemPaths {
|
|
||||||
inputDrvs = append(inputDrvs, Keys(drv[path].InputDrvs)...)
|
|
||||||
}
|
|
||||||
|
|
||||||
toActuallyBuild := filter(
|
|
||||||
overlapStrings(inputDrvs, toBuild),
|
|
||||||
drvNotIgnored,
|
|
||||||
)
|
|
||||||
|
|
||||||
drvs := make([]string, 0, len(toActuallyBuild))
|
|
||||||
for _, pkg := range toActuallyBuild {
|
|
||||||
fmt.Println(pkg)
|
|
||||||
drvs = append(drvs, fmt.Sprintf("%s^*", strings.TrimSpace(pkg)))
|
|
||||||
}
|
|
||||||
return drvs
|
|
||||||
}
|
|
|
@ -1,88 +0,0 @@
|
||||||
package ui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/charmbracelet/lipgloss"
|
|
||||||
"github.com/charmbracelet/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type Packages struct {
|
|
||||||
desc string
|
|
||||||
names []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParsePackages(lines []string, desc string) *Packages {
|
|
||||||
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 := strings.Replace(s[1], ".drv", "", 1)
|
|
||||||
names[i] = name
|
|
||||||
}
|
|
||||||
sort.Strings(names)
|
|
||||||
return &Packages{names: names, desc: desc}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Packages) Show(verbose bool) {
|
|
||||||
p.summary()
|
|
||||||
if !verbose || (len(p.names) == 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
pkgs := p.names
|
|
||||||
for _, pkg := range pkgs {
|
|
||||||
fmt.Printf(" %s\n", pkg)
|
|
||||||
}
|
|
||||||
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))),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Confirm asks the user for confirmation.
|
|
||||||
// valid inputs are: y/yes,n/no case insensitive.
|
|
||||||
func Confirm(s string) bool {
|
|
||||||
reader := bufio.NewReader(os.Stdin)
|
|
||||||
|
|
||||||
for {
|
|
||||||
fmt.Printf("%s [y/n]: ", s)
|
|
||||||
|
|
||||||
response, err := reader.ReadString('\n')
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
response = strings.ToLower(strings.TrimSpace(response))
|
|
||||||
switch response {
|
|
||||||
case "y", "yes":
|
|
||||||
return true
|
|
||||||
case "n", "no":
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import "oizys/cmd"
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
cmd.Execute()
|
|
||||||
}
|
|
Loading…
Reference in a new issue