derivation: parse nix derivation show
This time it's JSON, and actual intended behaviour.
This commit is contained in:
parent
68ae0efe19
commit
6aafccce4c
15
build.go
15
build.go
@ -2,9 +2,9 @@ package nixbuild
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"iter"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Build builds all entries yielded by installables.
|
||||
@ -32,18 +32,11 @@ func Build(ctx context.Context, installables iter.Seq[string]) error {
|
||||
return err
|
||||
}
|
||||
|
||||
for drv := range installables {
|
||||
if strings.HasSuffix(drv, ".drv") {
|
||||
// this is just what nix requires now :c
|
||||
drv += "^*"
|
||||
}
|
||||
if _, err := iw.Write([]byte(drv + "\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := WriteStdin(iw, installables); err != nil {
|
||||
return errors.Join(err, cmd.Wait())
|
||||
}
|
||||
|
||||
if err := iw.Close(); err != nil {
|
||||
return err
|
||||
return errors.Join(err, cmd.Wait())
|
||||
}
|
||||
|
||||
return cmd.Wait()
|
||||
|
@ -42,7 +42,20 @@ func main() {
|
||||
Flag(&flagVerbose, "v", command.BoolFlag(false), "Connect nix stderr").
|
||||
Flag(&flagJSON, "json", command.BoolFlag(false), "Serialise output in JSON when applicable")
|
||||
|
||||
c.Command("build", "Build a list of installables", func(args []string) error {
|
||||
c.Command("show", command.UsageInternal, func(args []string) error {
|
||||
if len(args) < 1 {
|
||||
return commandHandlerError("usage requires at least 1 argument")
|
||||
}
|
||||
|
||||
if drv, err := nixbuild.DerivationShow(ctx, slices.Values(args)); err != nil {
|
||||
return commandHandlerError(fmt.Sprintf("cannot show: %v", err))
|
||||
} else {
|
||||
log.Printf("got %d derivations:\n%#v", len(drv), drv)
|
||||
return nil
|
||||
}
|
||||
})
|
||||
|
||||
c.Command("build", command.UsageInternal, func(args []string) error {
|
||||
if len(args) < 1 {
|
||||
return commandHandlerError("build requires at least 1 argument")
|
||||
}
|
||||
|
88
derivation.go
Normal file
88
derivation.go
Normal file
@ -0,0 +1,88 @@
|
||||
package nixbuild
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"iter"
|
||||
)
|
||||
|
||||
type (
|
||||
// DerivationMap is the output of `nix derivation show`.
|
||||
DerivationMap map[string]Derivation
|
||||
|
||||
// Derivation is a description of a derivation.
|
||||
Derivation struct {
|
||||
// Args are arguments passed to Builder.
|
||||
Args []string `json:"args"`
|
||||
// Builder is the store path of the program that builds the [Derivation].
|
||||
Builder string `json:"builder"`
|
||||
// System is the value of pkgs.system during evaluation.
|
||||
System string `json:"system"`
|
||||
// Name is the user-facing name of a derivation, as seen in the nix store path suffix.
|
||||
Name string `json:"name"`
|
||||
|
||||
Environment json.RawMessage `json:"env"`
|
||||
InputDerivations InputDerivationsMap `json:"inputDrvs"`
|
||||
InputSources []string `json:"inputSrcs"`
|
||||
Outputs OutputsMap `json:"outputs"`
|
||||
}
|
||||
|
||||
// OutputsMap is an output name to [Output] map.
|
||||
OutputsMap map[string]Output
|
||||
|
||||
// Output is an output of a [Derivation].
|
||||
Output struct {
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
// InputDerivationsMap is a store path to metadata map.
|
||||
InputDerivationsMap map[string]InputDerivation
|
||||
|
||||
// InputDerivation contains input derivation metadata.
|
||||
InputDerivation struct {
|
||||
DynamicOutputs json.RawMessage `json:"dynamicOutputs"`
|
||||
Outputs []string `json:"outputs"`
|
||||
}
|
||||
)
|
||||
|
||||
// DerivationShow returns a [DerivationMap] describing all entries yielded by installables.
|
||||
func DerivationShow(ctx context.Context, installables iter.Seq[string]) (DerivationMap, error) {
|
||||
c, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
|
||||
cmd := Nix(c, CommandDerivation, CommandDerivationShow,
|
||||
FlagStdin)
|
||||
ir, iw := io.Pipe()
|
||||
cmd.Stdin = ir
|
||||
or, ow := io.Pipe()
|
||||
cmd.Stdout = ow
|
||||
if Stderr != nil {
|
||||
cmd.Stderr = Stderr
|
||||
}
|
||||
cmd.Cancel = func() error { _ = ow.Close(); return cmd.Process.Kill() }
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
done := make(chan error)
|
||||
var v DerivationMap
|
||||
go func() { done <- json.NewDecoder(or).Decode(&v) }()
|
||||
|
||||
if _, err := WriteStdin(iw, installables); err != nil {
|
||||
return nil, errors.Join(err, cmd.Wait())
|
||||
}
|
||||
if err := iw.Close(); err != nil {
|
||||
return nil, errors.Join(err, cmd.Wait())
|
||||
}
|
||||
|
||||
if err := cmd.Wait(); err != nil {
|
||||
// deferred cancel closes pipe
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err := <-done
|
||||
return v, err
|
||||
}
|
26
format.go
26
format.go
@ -2,12 +2,21 @@ package nixbuild
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"iter"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// CommandBuild build a derivation or fetch a store path
|
||||
CommandBuild = "build"
|
||||
// CommandDerivation work with derivations, Nix's notion of a build plan.
|
||||
CommandDerivation = "derivation"
|
||||
// CommandDerivationAdd add a store derivation
|
||||
CommandDerivationAdd = "add"
|
||||
// CommandDerivationShow show the contents of a store derivation
|
||||
CommandDerivationShow = "show"
|
||||
|
||||
// FlagDryRun show what this command would do without doing it.
|
||||
FlagDryRun = "--dry-run"
|
||||
@ -86,3 +95,20 @@ const (
|
||||
|
||||
// NixOSInstallable returns the nixos installable for a given flake and host.
|
||||
func NixOSInstallable(flake, host string) string { return flake + nixosSuffix0 + host + nixosSuffix1 }
|
||||
|
||||
// WriteStdin writes installables for a nix process running with [FlagStdin].
|
||||
func WriteStdin(w io.Writer, installables iter.Seq[string]) (int, error) {
|
||||
var count int
|
||||
for drv := range installables {
|
||||
if strings.HasSuffix(drv, ".drv") {
|
||||
// this is just what nix requires now :c
|
||||
drv += "^*"
|
||||
}
|
||||
n, err := w.Write([]byte(drv + "\n"))
|
||||
count += n
|
||||
if err != nil {
|
||||
return count, err
|
||||
}
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user