diff --git a/flake.nix b/flake.nix index 391c072..6f1fa64 100644 --- a/flake.nix +++ b/flake.nix @@ -27,14 +27,27 @@ templates = flakeOutputs.packages.${system}.tlaternet; }; - apps.${system}.default = let - inherit (self.packages.${system}) server templates; - inherit (nixpkgs.legacyPackages.${system}) writeShellScript; - in { - type = "app"; - program = builtins.toString (writeShellScript "tlaternet-webserver" '' - ${server}/bin/tlaternet-webserver --template-directory ${templates} - ''); + apps.${system} = { + default = let + inherit (self.packages.${system}) server templates; + inherit (nixpkgs.legacyPackages.${system}) writeShellScript; + in { + type = "app"; + program = builtins.toString (writeShellScript "tlaternet-webserver" '' + ${server}/bin/tlaternet-webserver --template-directory ${templates} + ''); + }; + + update = let + update-script = nixpkgs.legacyPackages.${system}.callPackage ./nix/update.nix { + cargo = flakeOutputs.rust-toolchain.cargo; + npm = nixpkgs.legacyPackages.${system}.nodePackages_latest.npm; + npm-check-updates = self.packages.${system}.templates.dependencies.npm-check-updates; + }; + in { + type = "app"; + program = "${update-script}/bin/update"; + }; }; nixosModules.default = import ./nix/module.nix {inherit self system;}; diff --git a/nix/scripts/update.sh b/nix/scripts/update.sh new file mode 100644 index 0000000..c5df1e1 --- /dev/null +++ b/nix/scripts/update.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +set -eu + +# The backticks aren't supposed to be shell expansion +# shellcheck disable=SC2016 +echo 'Note: Update the flake inputs with `nix flake update --commit-lockfile *first*`' + +# Make sure we're at the repo root +cd "$(git rev-parse --show-toplevel)" || exit + +# Update cargo deps +cd server || exit +cargo update + +if ! git diff --quiet Cargo.lock Cargo.toml; then + git commit -m 'server: Update cargo dependencies' Cargo.lock Cargo.toml +fi + +# Update template deps +cd ../templates || exit + +tmpdir="$(mktemp -dt 'npm-updates.XXXXXXXXXX')" +trap 'rm -r -- "$tmpdir"' EXIT + +# Ensure package.json is up to date so that npm-check-updates can read +# it +yq --output-format json package.yaml > package.json + +# Fetch package updates and prepare an update dict +yq -P eval-all '{"dependencies": select(fi==0)} * {"devDependencies": select(fi==1)}' \ + <(npm-check-updates --dep prod --jsonUpgraded) \ + <(npm-check-updates --dep dev --jsonUpgraded) \ + > "$tmpdir/updates.yaml" + +# Now apply these using yq +yq -P ". *= load(\"$tmpdir/updates.yaml\")" package.yaml > "$tmpdir/package.yaml.updated" + +# yq's in-place replacement sadly doesn't persist newlines currently, +# so we need to apply the changes in a roundabout way using diff. +diff --ignore-blank-lines <(yq '.' package.yaml) "$tmpdir/package.yaml.updated" > "$tmpdir/update.patch" || true +patch --no-backup-if-mismatch --merge --input="$tmpdir/update.patch" package.yaml + +# Update package.json again and get npm to update the package lock +# file +yq --output-format json package.yaml > package.json +npm install --package-lock-only + +if ! git diff --quiet package.yaml package-lock.json; then + git commit -m 'templates: Update npm dependencies' package.yaml package-lock.json +fi diff --git a/nix/update.nix b/nix/update.nix new file mode 100644 index 0000000..901097b --- /dev/null +++ b/nix/update.nix @@ -0,0 +1,14 @@ +{ + writeShellApplication, + cargo, + git, + nix, + npm, + npm-check-updates, + yq-go, +}: +writeShellApplication { + name = "update"; + runtimeInputs = [cargo git nix npm npm-check-updates yq-go]; + text = builtins.readFile ./scripts/update.sh; +}