cmd/nixbuild: implement command frontend

This commit is contained in:
Ophestra 2025-07-14 04:36:06 +09:00
parent beff1e98d8
commit a9d0130474
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q
4 changed files with 98 additions and 0 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@
*.so
*.dylib
*.pkg
/nixbuild
# Test binary, built with `go test -c`
*.test

93
cmd/nixbuild/main.go Normal file
View File

@ -0,0 +1,93 @@
package main
import (
"context"
"encoding/json"
"errors"
"fmt"
"log"
"os"
"os/signal"
"strings"
"syscall"
"git.gensokyo.uk/yonah/nixbuild"
"hakurei.app/command"
)
type commandHandlerError string
func (c commandHandlerError) Error() string { return string(c) }
func main() {
var (
flagNixOS bool
flagVerbose bool
flagJSON bool
)
c := command.New(os.Stderr, log.Printf, "nixbuild", func(args []string) error {
log.SetFlags(0)
log.SetPrefix("nixbuild: ")
nixbuild.Stdout = os.Stdout
if flagVerbose {
nixbuild.Stderr = os.Stderr
}
return nil
}).
Flag(&flagNixOS, "nixos", command.BoolFlag(false), "Interpret input as NixOS flake installable").
Flag(&flagVerbose, "v", command.BoolFlag(false), "Connect nix stderr").
Flag(&flagJSON, "json", command.BoolFlag(false), "Serialise output in JSON when applicable")
c.Command("instantiated", "Evaluate an installable and output all derivations it instantiated", func(args []string) error {
if len(args) != 1 {
return commandHandlerError("instantiated requires exactly 1 argument")
}
installable := args[0]
if flagNixOS {
fields := strings.SplitN(installable, "#", 2)
switch len(fields) {
case 2:
installable = nixbuild.NixOSInstallable(fields[0], fields[1])
case 1:
hostname, err := os.Hostname()
if err != nil {
return commandHandlerError(fmt.Sprintf("cannot get hostname: %v", err))
}
installable = nixbuild.NixOSInstallable(fields[0], hostname)
default:
return commandHandlerError("unexpected installable")
}
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
if v, err := nixbuild.EvalInstantiated(ctx, installable); err != nil {
return commandHandlerError(fmt.Sprintf("cannot evaluate for instantiated derivations: %v", err))
} else if flagJSON {
if err = json.NewEncoder(os.Stdout).Encode(v); err != nil {
return commandHandlerError(fmt.Sprintf("cannot serialise JSON: %v", err))
}
return nil
} else {
for _, drv := range v {
if strings.HasSuffix(drv, ".drv") {
fmt.Println(drv + "^*")
} else {
fmt.Println(drv)
}
}
return nil
}
})
c.MustParse(os.Args[1:], func(err error) {
var ce commandHandlerError
if errors.As(err, &ce) {
log.Fatal(ce.Error())
return
}
log.Fatalf("cannot parse command: %v", err)
})
}

2
go.mod
View File

@ -1,3 +1,5 @@
module git.gensokyo.uk/yonah/nixbuild
go 1.24.4
require hakurei.app v0.1.1

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
hakurei.app v0.1.1 h1:b1ooWWIdvvBRj0BCOmK2wLfVs3nvYbxEHtQX5DP6bos=
hakurei.app v0.1.1/go.mod h1:bWcF0vCO+ZOtZ2zK7L3e08sNb0kIkv1CBcdWTZtu1Gs=