+let
+ cfg = config.system.autoUpgradeWithPinch;
+ pull-repo-script = path: repo:
+ pkgs.writeShellScript "pull-repo" ''
+ set -eo pipefail
+
+ echo Pulling in ${escapeShellArg path} >&2
+
+ if [[ ! -e ${escapeShellArg path} ]];then
+ d=$(mktemp -d)
+ ${pkgs.git}/bin/git init "$d"
+ ${pkgs.git}/bin/git -C "$d" checkout -b \
+ ${escapeShellArg repo.localBranch}
+ ${pkgs.git}/bin/git -C "$d" remote add \
+ ${escapeShellArg repo.remoteName} \
+ ${escapeShellArg repo.url}
+ ${pkgs.git}/bin/git -C "$d" branch -u \
+ ${escapeShellArg repo.remoteBranch}
+ mkdir -p "$(dirname ${escapeShellArg path})"
+ mv "$d" ${escapeShellArg path}
+ fi
+
+ cd ${escapeShellArg path}
+
+ if [[ "$(${pkgs.git}/bin/git remote get-url \
+ ${escapeShellArg repo.remoteName})" != \
+ ${escapeShellArg repo.url} ]]
+ then
+ echo Expected git remote ${escapeShellArg repo.remoteName} \
+ to point at ${escapeShellArg repo.url} \
+ but it points at "$(${pkgs.git}/bin/git remote get-url \
+ ${escapeShellArg repo.remoteName})" >&2
+ ${
+ {
+ abort = "exit 1";
+ update = ''
+ echo Updating it >&2
+ ${pkgs.git}/bin/git -C "$d" remote set-url \
+ ${escapeShellArg repo.remoteName} \
+ ${escapeShellArg repo.url}
+ '';
+ }."${repo.onRemoteURLMismatch}"
+ }
+ fi
+
+ ${pkgs.git}/bin/git fetch \
+ ${escapeShellArg repo.remoteName} \
+ ${escapeShellArg repo.remoteBranch}
+
+ if [[ "$(${pkgs.git}/bin/git rev-parse --abbrev-ref HEAD)" != \
+ ${escapeShellArg repo.localBranch} ]]
+ then
+ echo Could not merge because currently-checked-out \
+ \""$(${pkgs.git}/bin/git rev-parse --abbrev-ref HEAD)"\" is not \
+ \"${escapeShellArg repo.localBranch}\"
+ ${
+ {
+ abort = "exit 1";
+ continue = "exit 0";
+ }."${repo.onBranchMismatch}"
+ }
+ fi
+
+
+ ${if repo.requireSignature then ''
+ PATH="${pkgs.keyedgit repo.signingKeys}/bin:$PATH" \
+ ${pkgs.polite-merge}/bin/polite-merge --ff-only --verify-signatures
+ '' else ''
+ ${pkgs.polite-merge}/bin/polite-merge --ff-only
+ ''}
+ '';
+
+ auto-upgrade-script = pkgs.writeShellScript "auto-upgrade" ''
+ ${pkgs.utillinux}/bin/flock /run/auto-upgrade-with-pinch ${
+ pkgs.writeShellScript "auto-upgrade-with-lock-held" ''
+ set -eo pipefail
+
+ in_tmpdir() {
+ d=$(${pkgs.coreutils}/bin/mktemp -d)
+ pushd "$d"
+ "$@"
+ popd
+ ${pkgs.coreutils}/bin/rm -r "$d"
+ }
+
+ # Pull updates
+ ${concatStringsSep "\n" (mapAttrsToList (path: repo: ''
+ /run/wrappers/bin/sudo -u ${escapeShellArg repo.user} \
+ ${pull-repo-script path repo}
+ '') cfg.repos)}
+
+ # Update channels
+ ${pkgs.pinch}/bin/pinch update ${escapeShellArgs cfg.pinchFiles}
+
+ # Build
+ in_tmpdir ${config.system.build.nixos-rebuild}/bin/nixos-rebuild build
+ ${concatStringsSep "\n" (mapAttrsToList (user: env: ''
+ /run/wrappers/bin/sudo -u ${escapeShellArg user} \
+ nix-build --no-out-link '<nixpkgs>' \
+ -A ${escapeShellArg env.package}
+ '') cfg.userEnvironments)}
+
+ # Install
+ ${config.system.build.nixos-rebuild}/bin/nixos-rebuild switch
+ ${concatStringsSep "\n" (mapAttrsToList (user: env: ''
+ /run/wrappers/bin/sudo -u ${escapeShellArg user} \
+ nix-env -f '<nixpkgs>' \
+ ${optionalString (env.otherPackagesAction != "keep") "-r"} \
+ -iA ${escapeShellArg env.package}
+ '') cfg.userEnvironments)}
+ ''
+ }
+ '';