package nix import ( "bufio" "io" "iter" "slices" "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" // FlagJson produce output in JSON format, suitable for consumption by another program. FlagJson = "--json" // FlagNoLink do not create symlinks to the build results. FlagNoLink = "--no-link" // FlagOutLink use path as prefix for the symlinks to the build results. It defaults to result. FlagOutLink = "--out-link" // FlagPrintOutPaths print the resulting output paths FlagPrintOutPaths = "--print-out-paths" // FlagProfile the profile to operate on. FlagProfile = "--profile" // FlagRebuild rebuild an already built package and compare the result to the existing store paths. FlagRebuild = "--rebuild" // FlagStdin read installables from the standard input. No default installable applied. FlagStdin = "--stdin" // FlagDebug set the logging verbosity level to 'debug'. FlagDebug = "--debug" // FlagLogFormat set the format of log output; one of raw, internal-json, bar or bar-with-logs. FlagLogFormat = "--log-format" // FlagPrintBuildLogs print full build logs on standard error. FlagPrintBuildLogs = "--print-build-logs" // FlagQuiet decrease the logging verbosity level. FlagQuiet = "--quiet" // FlagVerbose increase the logging verbosity level. FlagVerbose = "--verbose" // FlagOffline disable substituters and consider all previously downloaded files up-to-date. FlagOffline = "--offline" // FlagOption set the Nix configuration setting name to value (overriding nix.conf). FlagOption = "--option" // FlagRefresh consider all previously downloaded files out-of-date. FlagRefresh = "--refresh" // FlagRepair during evaluation, rewrite missing or corrupted files in the Nix store. During building, rebuild missing or corrupted store paths. FlagRepair = "--repair" // FlagVersion show version information. FlagVersion = "--version" // FlagKeepGoing keep going in case of failed builds, to the greatest extent possible. // That is, if building an input of some derivation fails, Nix will still build the other inputs, // but not the derivation itself. // Without this option, Nix stops if any build fails (except for builds of substitutes), // possibly killing builds in progress (in case of parallel or distributed builds). FlagKeepGoing = "--keep-going" // OptionEvalCache whether to use the flake evaluation cache. // Certain commands won’t have to evaluate when invoked for the second time with a particular version of a flake. // Intermediate results are not cached. OptionEvalCache = "eval-cache" ValueTrue = "true" ValueFalse = "false" ) const ( nixosSuffix0 = "#nixosConfigurations." nixosSuffix1 = ".config.system.build.toplevel" ) // 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 } const readStdinInitialCap = 1 << 10 // ReadStdin is the inverse of [WriteStdin]. func ReadStdin(r io.Reader) ([]string, error) { collective := make([]string, 0, readStdinInitialCap) scanner := bufio.NewScanner(r) for scanner.Scan() { if len(collective) == cap(collective) { // grow the buffer exponentially to minimise copies collective = slices.Grow(collective, cap(collective)) } p := scanner.Text() if strings.HasSuffix(p, ".drv^*") { p = p[:len(p)-2] } collective = append(collective, p) } return collective, scanner.Err() }