summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig6
-rw-r--r--biome.json12
-rw-r--r--default.nix18
-rw-r--r--flake.lock125
-rw-r--r--flake.nix135
-rw-r--r--nix/checks.nix46
-rw-r--r--nix/default.nix106
-rw-r--r--nix/fetchTree.nix172
-rw-r--r--overlay.nix3
-rw-r--r--package.json8
-rw-r--r--shell.nix25
11 files changed, 435 insertions, 221 deletions
diff --git a/.editorconfig b/.editorconfig
index 62e6253..f9e4a2e 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -7,11 +7,7 @@ charset = utf-8
indent_style = tab
indent_size = 4
-[*.{yml,yaml}]
-indent_style = space
-indent_size = 2
-
-[*.{nix,lock}]
+[*.{lock,nix,yml,yaml}]
indent_style = space
indent_size = 2
diff --git a/biome.json b/biome.json
new file mode 100644
index 0000000..80940cb
--- /dev/null
+++ b/biome.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://biomejs.dev/schemas/1.6.4/schema.json",
+ "formatter": {
+ "ignore": [
+ ".direnv/**",
+ ".git/**",
+ "dist/**",
+ "flake.lock",
+ "pnpm-lock.yaml"
+ ]
+ }
+}
diff --git a/default.nix b/default.nix
new file mode 100644
index 0000000..9db0433
--- /dev/null
+++ b/default.nix
@@ -0,0 +1,18 @@
+let
+ lock = builtins.fromJSON (builtins.readFile ./flake.lock);
+ fetchTree = import ./nix/fetchTree.nix;
+ flakeSources = builtins.mapAttrs (_: node: fetchTree node.locked) lock.nodes;
+in
+ {
+ nixpkgs ?
+ import sources.nixpkgs {
+ inherit system;
+ config = {};
+ overlays = [];
+ },
+ system ? builtins.currentSystem,
+ sources ? flakeSources,
+ }: let
+ pkgs' = import ./overlay.nix (nixpkgs // pkgs') nixpkgs;
+ in
+ pkgs'
diff --git a/flake.lock b/flake.lock
index c1dc3af..ae38a40 100644
--- a/flake.lock
+++ b/flake.lock
@@ -1,64 +1,5 @@
{
"nodes": {
- "flake-parts": {
- "inputs": {
- "nixpkgs-lib": [
- "nixpkgs"
- ]
- },
- "locked": {
- "lastModified": 1712014858,
- "narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
- "owner": "hercules-ci",
- "repo": "flake-parts",
- "rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
- "type": "github"
- },
- "original": {
- "owner": "hercules-ci",
- "repo": "flake-parts",
- "type": "github"
- }
- },
- "flake-utils": {
- "inputs": {
- "systems": "systems"
- },
- "locked": {
- "lastModified": 1710146030,
- "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
- "owner": "numtide",
- "repo": "flake-utils",
- "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "flake-utils",
- "type": "github"
- }
- },
- "gitignore": {
- "inputs": {
- "nixpkgs": [
- "pre-commit",
- "nixpkgs"
- ]
- },
- "locked": {
- "lastModified": 1709087332,
- "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
- "owner": "hercules-ci",
- "repo": "gitignore.nix",
- "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
- "type": "github"
- },
- "original": {
- "owner": "hercules-ci",
- "repo": "gitignore.nix",
- "type": "github"
- }
- },
"nixpkgs": {
"locked": {
"lastModified": 1712849433,
@@ -75,73 +16,9 @@
"type": "github"
}
},
- "pre-commit": {
- "inputs": {
- "flake-compat": [],
- "flake-utils": "flake-utils",
- "gitignore": "gitignore",
- "nixpkgs": [
- "nixpkgs"
- ],
- "nixpkgs-stable": [
- "nixpkgs"
- ]
- },
- "locked": {
- "lastModified": 1712897695,
- "narHash": "sha256-nMirxrGteNAl9sWiOhoN5tIHyjBbVi5e2tgZUgZlK3Y=",
- "owner": "cachix",
- "repo": "pre-commit-hooks.nix",
- "rev": "40e6053ecb65fcbf12863338a6dcefb3f55f1bf8",
- "type": "github"
- },
- "original": {
- "owner": "cachix",
- "repo": "pre-commit-hooks.nix",
- "type": "github"
- }
- },
"root": {
"inputs": {
- "flake-parts": "flake-parts",
- "nixpkgs": "nixpkgs",
- "pre-commit": "pre-commit",
- "treefmt-nix": "treefmt-nix"
- }
- },
- "systems": {
- "locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
- "owner": "nix-systems",
- "repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
- "type": "github"
- },
- "original": {
- "owner": "nix-systems",
- "repo": "default",
- "type": "github"
- }
- },
- "treefmt-nix": {
- "inputs": {
- "nixpkgs": [
- "nixpkgs"
- ]
- },
- "locked": {
- "lastModified": 1711963903,
- "narHash": "sha256-N3QDhoaX+paWXHbEXZapqd1r95mdshxToGowtjtYkGI=",
- "owner": "numtide",
- "repo": "treefmt-nix",
- "rev": "49dc4a92b02b8e68798abd99184f228243b6e3ac",
- "type": "github"
- },
- "original": {
- "owner": "numtide",
- "repo": "treefmt-nix",
- "type": "github"
+ "nixpkgs": "nixpkgs"
}
}
},
diff --git a/flake.nix b/flake.nix
index 65ee21f..129b5d7 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,93 +1,56 @@
{
description = "seth's website";
- inputs = {
- nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
-
- flake-parts = {
- url = "github:hercules-ci/flake-parts";
- inputs.nixpkgs-lib.follows = "nixpkgs";
- };
-
- treefmt-nix = {
- url = "github:numtide/treefmt-nix";
- inputs.nixpkgs.follows = "nixpkgs";
- };
-
- pre-commit = {
- url = "github:cachix/pre-commit-hooks.nix";
- inputs = {
- nixpkgs.follows = "nixpkgs";
- nixpkgs-stable.follows = "nixpkgs";
- flake-compat.follows = "";
- };
- };
- };
-
- outputs = inputs:
- inputs.flake-parts.lib.mkFlake {inherit inputs;} {
- imports = with inputs; [
- treefmt-nix.flakeModule
- pre-commit.flakeModule
- ];
-
- systems = [
- "x86_64-linux"
- "aarch64-linux"
- "x86_64-darwin"
- "aarch64-darwin"
- ];
-
- perSystem = {
- lib,
+ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+
+ outputs = {
+ self,
+ nixpkgs,
+ }: let
+ systems = [
+ "x86_64-linux"
+ "aarch64-linux"
+ "x86_64-darwin"
+ "aarch64-darwin"
+ ];
+
+ forAllSystems = fn: nixpkgs.lib.genAttrs systems (system: fn nixpkgs.legacyPackages.${system});
+ in {
+ checks = forAllSystems (
+ {
pkgs,
- config,
- self',
+ system,
...
- }: let
- nodejs-slim = pkgs.nodejs-slim_20; # this should be the current lts
- corepack = pkgs.corepack_20;
-
- enableAll = lib.flip lib.genAttrs (lib.const {enable = true;});
- in {
- treefmt = {
- projectRootFile = ".git/config";
-
- programs = enableAll ["alejandra" "deadnix" "prettier"];
-
- settings.global = {
- excludes = [
- "./node_modules/*"
- "./dist/*"
- "./.astro/*"
- "flake.lock"
- "pnpm-lock.yaml"
- ];
- };
- };
-
- pre-commit.settings.hooks =
- (enableAll [
- "actionlint"
- "eclint"
- "eslint"
- "nil"
- "statix"
- "treefmt"
- ])
- // {
- treefmt.package = config.treefmt.build.wrapper;
- };
-
- devShells.default = pkgs.mkShellNoCC {
- shellHook = config.pre-commit.installationScript;
- packages = [
- self'.formatter
- nodejs-slim
- # use pnpm from package.json
- corepack
- ];
- };
+ }:
+ import ./nix/checks.nix (pkgs // {formatter = self.formatter.${system};})
+ );
+
+ devShells = forAllSystems ({
+ pkgs,
+ system,
+ ...
+ }: {
+ default = import ./shell.nix {
+ inherit system;
+ nixpkgs = pkgs;
+ formatter = self.formatter.${system};
+ };
+ });
+
+ formatter = forAllSystems (pkgs: pkgs.alejandra);
+
+ packages = forAllSystems ({
+ pkgs,
+ system,
+ ...
+ }: let
+ pkgs' = import ./. {
+ inherit system;
+ nixpkgs = pkgs;
};
- };
+ in
+ pkgs' // {default = pkgs'.website;});
+
+ overlays.default = final: prev: import ./overlay.nix final prev;
+ };
}
diff --git a/nix/checks.nix b/nix/checks.nix
new file mode 100644
index 0000000..c7f6547
--- /dev/null
+++ b/nix/checks.nix
@@ -0,0 +1,46 @@
+{
+ lib,
+ runCommand,
+ actionlint,
+ biome,
+ deadnix,
+ formatter,
+ eclint,
+ statix,
+ ...
+}: {
+ actionlint = runCommand "check-actionlint" {} ''
+ ${lib.getExe actionlint} ${../.github/workflows}/*
+ touch $out
+ '';
+
+ biome-fmt = runCommand "check-biome-fmt" {} ''
+ ${lib.getExe biome} format ${../.}/**/*
+ touch $out
+ '';
+
+ biome-lint = runCommand "check-biome-lint" {} ''
+ ${lib.getExe biome} lint ${../.}/**/*
+ touch $out
+ '';
+
+ deadnix = runCommand "check-deadnix" {} ''
+ ${lib.getExe deadnix} ${../.}
+ touch $out
+ '';
+
+ "${formatter.pname}" = runCommand "check-${formatter.pname}" {} ''
+ ${lib.getExe formatter} --check ${../.}
+ touch $out
+ '';
+
+ eclint = runCommand "check-eclint" {} ''
+ ${lib.getExe eclint} ${../.}/**/*
+ touch $out
+ '';
+
+ statix = runCommand "check-statix" {} ''
+ ${lib.getExe statix} check ${../.}
+ touch $out
+ '';
+}
diff --git a/nix/default.nix b/nix/default.nix
new file mode 100644
index 0000000..a0dcda0
--- /dev/null
+++ b/nix/default.nix
@@ -0,0 +1,106 @@
+{
+ lib,
+ stdenvNoCC,
+ cacert,
+ jq,
+ moreutils,
+ nodejs,
+}:
+stdenvNoCC.mkDerivation (finalAttrs: {
+ name = "getchoo-website";
+
+ src = lib.fileset.toSource {
+ root = ../.;
+ fileset = lib.fileset.gitTracked ../.;
+ };
+
+ __structuredAttrs = true;
+
+ nativeBuildInputs = [
+ nodejs
+ nodejs.pkgs.pnpm
+ ];
+
+ env = {
+ pnpmDeps = stdenvNoCC.mkDerivation (finalAttrs': {
+ name = "${finalAttrs.name}-pnpm-deps";
+ inherit (finalAttrs) src;
+
+ __structuredAttrs = true;
+
+ nativeBuildInputs = [
+ cacert
+ jq
+ moreutils
+ nodejs.pkgs.pnpm
+ ];
+
+ dontConfigure = true;
+ dontBuild = true;
+ doCheck = false;
+
+ installPhase = ''
+ runHook preInstall
+
+ export HOME="$(mktemp -d)"
+ pnpm config set store-dir "$out"
+ pnpm install --force --frozen-lockfile --ignore-script
+
+ runHook postInstall
+ '';
+
+ fixupPhase = ''
+ runHook preFixup
+
+ rm -rf "$out"/v3/tmp
+ for f in $(find "$out" -name "*.json"); do
+ sed -i -E -e 's/"checkedAt":[0-9]+,//g' $f
+ jq --sort-keys . $f | sponge $f
+ done
+
+ runHook postFixup
+ '';
+
+ outputHashMode = "recursive";
+ outputHash = "sha256-pKo1t9K24HUOjjfwfubx+JorlAJeshAQBLSABRoSF/k=";
+ });
+ };
+
+ postConfigure = ''
+ export HOME="$(mktemp -d)"
+ export STORE_PATH="$(mktemp -d)"
+
+ cp -rT "$pnpmDeps" "$STORE_PATH"
+ chmod -R +w "$STORE_PATH"
+
+ pnpm config set store-dir "$STORE_PATH"
+
+ pnpm install --force --frozen-lockfile --ignore-script --offline
+
+ patchShebangs node_modules/{*,.*}
+ '';
+
+ buildPhase = ''
+ runHook preBuild
+ pnpm run build
+ runHook postBuild
+ '';
+
+ installPhase = ''
+ runHook preInstall
+ mv dist "$out"
+ runHook postInstall
+ '';
+
+ checkPhase = ''
+ runHook preCheck
+ pnpm run check
+ runHook postCheck
+ '';
+
+ meta = with lib; {
+ homepage = "https://github.com/getchoo/website";
+ license = licenses.mit;
+ maintainers = with maintainers; [getchoo];
+ };
+})
diff --git a/nix/fetchTree.nix b/nix/fetchTree.nix
new file mode 100644
index 0000000..26de85b
--- /dev/null
+++ b/nix/fetchTree.nix
@@ -0,0 +1,172 @@
+# this code is slightly modified from https://github.com/edolstra/flake-compat
+##
+## Copyright (c) 2020-2021 Eelco Dolstra and the flake-compat contributors
+##
+## Permission is hereby granted, free of charge, to any person obtaining
+## a copy of this software and associated documentation files (the
+## "Software"), to deal in the Software without restriction, including
+## without limitation the rights to use, copy, modify, merge, publish,
+## distribute, sublicense, and/or sell copies of the Software, and to
+## permit persons to whom the Software is furnished to do so, subject to
+## the following conditions:
+##
+## The above copyright notice and this permission notice shall be
+## included in all copies or substantial portions of the Software.
+##
+## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+## NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+## LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+## OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+## WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+let
+ formatSecondsSinceEpoch = t: let
+ rem = x: y: x - x / y * y;
+ days = t / 86400;
+ secondsInDay = rem t 86400;
+ hours = secondsInDay / 3600;
+ minutes = (rem secondsInDay 3600) / 60;
+ seconds = rem t 60;
+
+ # Courtesy of https://stackoverflow.com/a/32158604.
+ z = days + 719468;
+ era =
+ (
+ if z >= 0
+ then z
+ else z - 146096
+ )
+ / 146097;
+ doe = z - era * 146097;
+ yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
+ y = yoe + era * 400;
+ doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
+ mp = (5 * doy + 2) / 153;
+ d = doy - (153 * mp + 2) / 5 + 1;
+ m =
+ mp
+ + (
+ if mp < 10
+ then 3
+ else -9
+ );
+ y' =
+ y
+ + (
+ if m <= 2
+ then 1
+ else 0
+ );
+
+ pad = s:
+ if builtins.stringLength s < 2
+ then "0" + s
+ else s;
+ in "${toString y'}${pad (toString m)}${pad (toString d)}${pad (toString hours)}${pad (toString minutes)}${pad (toString seconds)}";
+
+ fetchTree = info:
+ if info.type == "github"
+ then {
+ outPath =
+ fetchTarball
+ (
+ {url = "https://api.${info.host or "github.com"}/repos/${info.owner}/${info.repo}/tarball/${info.rev}";}
+ // (
+ if info ? narHash
+ then {sha256 = info.narHash;}
+ else {}
+ )
+ );
+ inherit (info) rev lastModified narHash;
+ shortRev = builtins.substring 0 7 info.rev;
+ lastModifiedDate = formatSecondsSinceEpoch info.lastModified;
+ }
+ else if info.type == "git"
+ then
+ {
+ outPath =
+ builtins.fetchGit
+ (
+ {inherit (info) url;}
+ // (
+ if info ? rev
+ then {inherit (info) rev;}
+ else {}
+ )
+ // (
+ if info ? ref
+ then {inherit (info) ref;}
+ else {}
+ )
+ // (
+ if info ? submodules
+ then {inherit (info) submodules;}
+ else {}
+ )
+ );
+ inherit (info) lastModified narHash;
+ lastModifiedDate = formatSecondsSinceEpoch info.lastModified;
+ }
+ // (
+ if info ? rev
+ then {
+ inherit (info) rev;
+ shortRev = builtins.substring 0 7 info.rev;
+ }
+ else {
+ }
+ )
+ else if info.type == "path"
+ then {
+ outPath = builtins.path {inherit (info) path;};
+ inherit (info) narHash;
+ }
+ else if info.type == "tarball"
+ then {
+ outPath =
+ fetchTarball
+ (
+ {inherit (info) url;}
+ // (
+ if info ? narHash
+ then {sha256 = info.narHash;}
+ else {}
+ )
+ );
+ }
+ else if info.type == "gitlab"
+ then {
+ inherit (info) rev narHash lastModified;
+ outPath =
+ fetchTarball
+ (
+ {url = "https://${info.host or "gitlab.com"}/api/v4/projects/${info.owner}%2F${info.repo}/repository/archive.tar.gz?sha=${info.rev}";}
+ // (
+ if info ? narHash
+ then {sha256 = info.narHash;}
+ else {}
+ )
+ );
+ shortRev = builtins.substring 0 7 info.rev;
+ }
+ else if info.type == "sourcehut"
+ then {
+ inherit (info) rev narHash lastModified;
+ outPath =
+ fetchTarball
+ (
+ {url = "https://${info.host or "git.sr.ht"}/${info.owner}/${info.repo}/archive/${info.rev}.tar.gz";}
+ // (
+ if info ? narHash
+ then {sha256 = info.narHash;}
+ else {}
+ )
+ );
+ shortRev = builtins.substring 0 7 info.rev;
+ }
+ else
+ # FIXME: add Mercurial, tarball inputs.
+ throw "flake input has unsupported input type '${info.type}'";
+in
+ fetchTree
diff --git a/overlay.nix b/overlay.nix
new file mode 100644
index 0000000..1a41859
--- /dev/null
+++ b/overlay.nix
@@ -0,0 +1,3 @@
+_: prev: {
+ website = prev.callPackage ./nix {};
+}
diff --git a/package.json b/package.json
index 81fb75f..1a2da6e 100644
--- a/package.json
+++ b/package.json
@@ -41,12 +41,8 @@
"prettier"
],
"parser": "@typescript-eslint/parser",
- "plugins": [
- "@typescript-eslint"
- ],
+ "plugins": ["@typescript-eslint"],
"root": true,
- "ignorePatterns": [
- "dist/**"
- ]
+ "ignorePatterns": ["dist/**"]
}
}
diff --git a/shell.nix b/shell.nix
new file mode 100644
index 0000000..ecbb896
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,25 @@
+let
+ lock = builtins.fromJSON (builtins.readFile ./flake.lock);
+ fetchTree = import ./nix/fetchTree.nix;
+ flakeSources = builtins.mapAttrs (_: node: fetchTree node.locked) lock.nodes;
+in
+ {
+ nixpkgs ?
+ import sources.nixpkgs {
+ inherit system;
+ config = {};
+ overlays = [];
+ },
+ system ? builtins.currentSystem,
+ sources ? flakeSources,
+ formatter ? nixpkgs.alejandra,
+ }:
+ nixpkgs.mkShellNoCC {
+ packages = [
+ formatter
+ nixpkgs.biome
+ nixpkgs.nodejs-slim
+ # use package manager from package.json
+ nixpkgs.corepack
+ ];
+ }