A small exec wrapper which will query the lorri daemon for the last few events, and if it sees a build running for the current project (searching upwards for shell.nix), it will wait for the build to finish before executing the command (in the new direnv environment). TODO: should patch lorri so that it can provide this information in a better digestive format; right now it might have a later evaluation running, so it’s hard to know which completion to wait for … Change-Id: I8fa4a10484830a731fe3ec58f2694498f46a496c Reviewed-on: https://cl.tvl.fyi/c/depot/+/5903 Tested-by: BuildkiteCI Reviewed-by: Profpatsch <mail@profpatsch.de>
		
			
				
	
	
		
			212 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			212 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ depot, pkgs, lib, ... }:
 | 
						||
 | 
						||
let
 | 
						||
  bins = depot.nix.getBins pkgs.stow [ "stow" ]
 | 
						||
    // depot.nix.getBins pkgs.coreutils [ "mkdir" "ln" "printenv" "rm" ]
 | 
						||
    // depot.nix.getBins pkgs.xe [ "xe" ]
 | 
						||
    // depot.nix.getBins pkgs.lr [ "lr" ]
 | 
						||
    // depot.nix.getBins pkgs.nix [ "nix-store" ]
 | 
						||
  ;
 | 
						||
 | 
						||
  # run stow to populate the target directory with the given stow package, read from stowDir.
 | 
						||
  # Bear in mind that `stowDirOriginPath` should always be semantically bound to the given `stowDir`, otherwise stow might become rather confused.
 | 
						||
  runStow =
 | 
						||
    {
 | 
						||
      # “stow package” to stow (see manpage)
 | 
						||
      # TODO: allow this function to un-stow multiple packages!
 | 
						||
      stowPackage
 | 
						||
    , # “target directory” to stow in (see manpage)
 | 
						||
      targetDir
 | 
						||
    , # The “stow directory” (see manpage), containing “stow packages” (see manpage)
 | 
						||
      stowDir
 | 
						||
    , # representative directory for the stowDir in the file system, against which stow will create relative links.
 | 
						||
      # ATTN: this is always overwritten with the contents of `stowDir`! You shouldn’t re-use the same `stowDirOriginPath` for different `stowDir`s, otherwise there might be surprises.
 | 
						||
      stowDirOriginPath
 | 
						||
    ,
 | 
						||
    }: depot.nix.writeExecline "stow-${stowPackage}" { } [
 | 
						||
      # first, create a temporary stow directory to use as source
 | 
						||
      # (stow will use it to determine the origin of files)
 | 
						||
      "if"
 | 
						||
      [ bins.mkdir "-p" stowDirOriginPath ]
 | 
						||
      # remove old symlinks
 | 
						||
      "if"
 | 
						||
      [
 | 
						||
        "pipeline"
 | 
						||
        [
 | 
						||
          bins.lr
 | 
						||
          "-0"
 | 
						||
          "-t"
 | 
						||
          "depth == 1 && type == l"
 | 
						||
          stowDirOriginPath
 | 
						||
        ]
 | 
						||
        bins.xe
 | 
						||
        "-0"
 | 
						||
        bins.rm
 | 
						||
      ]
 | 
						||
      # create an indirect gc root so our config is not cleaned under our asses by a garbage collect
 | 
						||
      "if"
 | 
						||
      [
 | 
						||
        bins.nix-store
 | 
						||
        "--realise"
 | 
						||
        "--indirect"
 | 
						||
        "--add-root"
 | 
						||
        "${stowDirOriginPath}/.nix-stowdir-gc-root"
 | 
						||
        stowDir
 | 
						||
      ]
 | 
						||
      # populate with new stow targets
 | 
						||
      "if"
 | 
						||
      [
 | 
						||
        "elglob"
 | 
						||
        "-w0"
 | 
						||
        "stowPackages"
 | 
						||
        "${stowDir}/*"
 | 
						||
        bins.ln
 | 
						||
        "--force"
 | 
						||
        "-st"
 | 
						||
        stowDirOriginPath
 | 
						||
        "$stowPackages"
 | 
						||
      ]
 | 
						||
      # stow always looks for $HOME/.stowrc to read more arguments
 | 
						||
      "export"
 | 
						||
      "HOME"
 | 
						||
      "/homeless-shelter"
 | 
						||
      bins.stow
 | 
						||
      # always run restow for now; this does more stat but will remove stale links
 | 
						||
      "--restow"
 | 
						||
      "--dir"
 | 
						||
      stowDirOriginPath
 | 
						||
      "--target"
 | 
						||
      targetDir
 | 
						||
      stowPackage
 | 
						||
    ];
 | 
						||
 | 
						||
  # create a stow dir from a list of drv paths and a stow package name.
 | 
						||
  makeStowDir =
 | 
						||
    (with depot.nix.yants;
 | 
						||
    defun
 | 
						||
      [
 | 
						||
        (list (struct {
 | 
						||
          originalDir = drv;
 | 
						||
          stowPackage = string;
 | 
						||
        }))
 | 
						||
        drv
 | 
						||
      ])
 | 
						||
      (dirs:
 | 
						||
        depot.nix.runExecline "make-stow-dir"
 | 
						||
          {
 | 
						||
            stdin = lib.pipe dirs [
 | 
						||
              (map depot.users.Profpatsch.netencode.gen.dwim)
 | 
						||
              depot.users.Profpatsch.netstring.toNetstringList
 | 
						||
            ];
 | 
						||
          } [
 | 
						||
          "importas"
 | 
						||
          "out"
 | 
						||
          "out"
 | 
						||
          "if"
 | 
						||
          [ bins.mkdir "-p" "$out" ]
 | 
						||
          "forstdin"
 | 
						||
          "-d"
 | 
						||
          ""
 | 
						||
          "-o"
 | 
						||
          "0"
 | 
						||
          "line"
 | 
						||
          "pipeline"
 | 
						||
          [
 | 
						||
            depot.users.Profpatsch.execline.print-one-env
 | 
						||
            "line"
 | 
						||
          ]
 | 
						||
          depot.users.Profpatsch.netencode.record-splice-env
 | 
						||
          "importas"
 | 
						||
          "-ui"
 | 
						||
          "originalDir"
 | 
						||
          "originalDir"
 | 
						||
          "importas"
 | 
						||
          "-ui"
 | 
						||
          "stowPackage"
 | 
						||
          "stowPackage"
 | 
						||
          bins.ln
 | 
						||
          "-sT"
 | 
						||
          "$originalDir"
 | 
						||
          "\${out}/\${stowPackage}"
 | 
						||
        ]);
 | 
						||
 | 
						||
  # this is a dumb way of generating a pure list of packages from a depot namespace.
 | 
						||
  readTreeNamespaceDrvs = namespace:
 | 
						||
    lib.pipe namespace [
 | 
						||
      (lib.filterAttrs (_: v: lib.isDerivation v))
 | 
						||
      (lib.mapAttrsToList (k: v: {
 | 
						||
        name = k;
 | 
						||
        drv = v;
 | 
						||
      }))
 | 
						||
    ];
 | 
						||
 | 
						||
  scriptsStow =
 | 
						||
    lib.pipe { } [
 | 
						||
      (_: makeStowDir [{
 | 
						||
        stowPackage = "scripts";
 | 
						||
        originalDir = pkgs.linkFarm "scripts-farm"
 | 
						||
          ([
 | 
						||
            {
 | 
						||
              name = "scripts/ytextr";
 | 
						||
              path = depot.users.Profpatsch.ytextr;
 | 
						||
            }
 | 
						||
            {
 | 
						||
              name = "scripts/lorri-wait-for-eval";
 | 
						||
              path = depot.users.Profpatsch.lorri-wait-for-eval;
 | 
						||
            }
 | 
						||
            {
 | 
						||
              name = "scripts/lw";
 | 
						||
              path = depot.users.Profpatsch.lorri-wait-for-eval;
 | 
						||
            }
 | 
						||
 | 
						||
          ]
 | 
						||
          ++
 | 
						||
          (lib.pipe depot.users.Profpatsch.aliases [
 | 
						||
            readTreeNamespaceDrvs
 | 
						||
            (map ({ name, drv }: {
 | 
						||
              name = "scripts/${name}";
 | 
						||
              path = drv;
 | 
						||
            }))
 | 
						||
          ]));
 | 
						||
      }])
 | 
						||
      (d: runStow {
 | 
						||
        stowDir = d;
 | 
						||
        stowPackage = "scripts";
 | 
						||
        targetDir = "/home/philip";
 | 
						||
        stowDirOriginPath = "/home/philip/.local/share/nix-home/stow-origin";
 | 
						||
      })
 | 
						||
    ];
 | 
						||
 | 
						||
 | 
						||
 | 
						||
  terminalEmulatorStow =
 | 
						||
    lib.pipe { } [
 | 
						||
      (_: makeStowDir [{
 | 
						||
        stowPackage = "terminal-emulator";
 | 
						||
        originalDir = pkgs.linkFarm "terminal-emulator-farm"
 | 
						||
          ([
 | 
						||
            {
 | 
						||
              name = "bin/terminal-emulator";
 | 
						||
              path = depot.users.Profpatsch.alacritty;
 | 
						||
            }
 | 
						||
          ]);
 | 
						||
 | 
						||
      }])
 | 
						||
      (d: runStow {
 | 
						||
        stowDir = d;
 | 
						||
        stowPackage = "terminal-emulator";
 | 
						||
        targetDir = "/home/philip";
 | 
						||
        # TODO: this should only be done once, in a single runStow instead of multiple
 | 
						||
        stowDirOriginPath = "/home/philip/.local/share/nix-home/stow-origin-terminal-emulator";
 | 
						||
      })
 | 
						||
    ];
 | 
						||
 | 
						||
in
 | 
						||
 | 
						||
# TODO: run multiple stows with runStow?
 | 
						||
  # TODO: temp setup
 | 
						||
depot.nix.writeExecline "nix-home" { } [
 | 
						||
  "if"
 | 
						||
  [ scriptsStow ]
 | 
						||
  terminalEmulatorStow
 | 
						||
]
 |