~zainab/blog

c5d6d27d34f3da00822d75cb32458e25adbb9441 — zainab-ali 10 months ago 0dfbfe9 main
Add pre-commit.
15 files changed, 330 insertions(+), 244 deletions(-)

M .gitignore
M default.nix
M flake.lock
M flake.nix
M nix/derivation.nix
M nix/favicon.nix
M nix/ibm-plex.nix
M nix/python.nix
M nix/render.bash
M nix/reveal.nix
M nix/snippets.bash
M nix/snippets.nix
M nix/source-code-pro.nix
M nix/source-serif-pro.nix
D src/assets/images/2023-06-07-scaladays-pierian-stream/rename.bash
M .gitignore => .gitignore +2 -0
@@ 19,3 19,5 @@ src/WOFF2/
src/OTF/
src/VAR/
src/TTF/

.pre-commit-config.yaml
\ No newline at end of file

M default.nix => default.nix +1 -4
@@ 1,5 1,2 @@
{
  pkgs ? import <nixpkgs> {}
}:
{pkgs ? import <nixpkgs> {}}:
pkgs.callPackage (import ./nix/derivation.nix) {}


M flake.lock => flake.lock +67 -1
@@ 130,6 130,22 @@
        "type": "github"
      }
    },
    "flake-compat_2": {
      "flake": false,
      "locked": {
        "lastModified": 1673956053,
        "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
        "owner": "edolstra",
        "repo": "flake-compat",
        "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
        "type": "github"
      },
      "original": {
        "owner": "edolstra",
        "repo": "flake-compat",
        "type": "github"
      }
    },
    "flake-parts": {
      "inputs": {
        "nixpkgs-lib": [


@@ 200,6 216,27 @@
        "url": "https://gitlab.haskell.org/bgamari/ghc-utils"
      }
    },
    "gitignore": {
      "inputs": {
        "nixpkgs": [
          "pre-commit-hooks",
          "nixpkgs"
        ]
      },
      "locked": {
        "lastModified": 1660459072,
        "narHash": "sha256-8DFJjXG8zqoONA1vXtgeKXy68KdJL5UaXR8NtVMUbx8=",
        "owner": "hercules-ci",
        "repo": "gitignore.nix",
        "rev": "a20de23b925fd8264fd7fad6454652e142fd7f73",
        "type": "github"
      },
      "original": {
        "owner": "hercules-ci",
        "repo": "gitignore.nix",
        "type": "github"
      }
    },
    "gomod2nix": {
      "flake": false,
      "locked": {


@@ 334,6 371,34 @@
        "type": "github"
      }
    },
    "pre-commit-hooks_2": {
      "inputs": {
        "flake-compat": "flake-compat_2",
        "flake-utils": [
          "flake-utils"
        ],
        "gitignore": "gitignore",
        "nixpkgs": [
          "nixpkgs"
        ],
        "nixpkgs-stable": [
          "nixpkgs"
        ]
      },
      "locked": {
        "lastModified": 1691747570,
        "narHash": "sha256-J3fnIwJtHVQ0tK2JMBv4oAmII+1mCdXdpeCxtIsrL2A=",
        "owner": "cachix",
        "repo": "pre-commit-hooks.nix",
        "rev": "c5ac3aa3324bd8aebe8622a3fc92eeb3975d317a",
        "type": "github"
      },
      "original": {
        "owner": "cachix",
        "repo": "pre-commit-hooks.nix",
        "type": "github"
      }
    },
    "pruned-racket-catalog": {
      "flake": false,
      "locked": {


@@ 356,7 421,8 @@
        "dream2nix": "dream2nix",
        "flake-utils": "flake-utils",
        "nix-filter": "nix-filter",
        "nixpkgs": "nixpkgs"
        "nixpkgs": "nixpkgs",
        "pre-commit-hooks": "pre-commit-hooks_2"
      }
    },
    "systems": {

M flake.nix => flake.nix +97 -72
@@ 7,87 7,112 @@
    nix-filter.url = "github:numtide/nix-filter";
    dream2nix.url = "github:nix-community/dream2nix";
    dream2nix.inputs.nixpkgs.follows = "nixpkgs";
    pre-commit-hooks = {
      url = github:cachix/pre-commit-hooks.nix;
      inputs.nixpkgs-stable.follows = "nixpkgs";
      inputs.nixpkgs.follows = "nixpkgs";
      inputs.flake-utils.follows = "flake-utils";
    };
  };

  outputs = { self, nixpkgs, flake-utils, nix-filter, dream2nix }:
  outputs = {
    self,
    nixpkgs,
    flake-utils,
    nix-filter,
    dream2nix,
    pre-commit-hooks,
  }:
    flake-utils.lib.eachSystem [
      "x86_64-linux"
    ] (system: let
      pkgs = nixpkgs.legacyPackages.${system};
      serve = with pkgs;
        writeScriptBin "serve"
    ] (
      system: let
        pkgs = nixpkgs.legacyPackages.${system};
        serve = with pkgs;
          writeScriptBin "serve"
          ''
    #!${stdenv.shell}
    $(which raco) pollen start src
    '';
      source-serif-pro = pkgs.callPackage ./nix/source-serif-pro.nix { };
      source-code-pro = pkgs.callPackage ./nix/source-code-pro.nix { };
      ibm-plex = pkgs.callPackage ./nix/ibm-plex.nix { };
      fontLocal = with pkgs;
        writeScriptBin "gen-font-links"
            #!${stdenv.shell}
            $(which raco) pollen start src
          '';
        source-serif-pro = pkgs.callPackage ./nix/source-serif-pro.nix {};
        source-code-pro = pkgs.callPackage ./nix/source-code-pro.nix {};
        ibm-plex = pkgs.callPackage ./nix/ibm-plex.nix {};
        fontLocal = with pkgs;
          writeScriptBin "gen-font-links"
          ''
    #!${stdenv.shell}
    cp -r ${source-serif-pro.out}/* src
    cp -r ${source-code-pro.out}/* src
    cp -r ${ibm-plex.out}/* src
    chmod -R u+w src
    '';
      snippets = pkgs.callPackage ./nix/snippets.nix { };
      snippetsLocal = with pkgs;
        writeScriptBin "gen-snippets"
            #!${stdenv.shell}
            cp -r ${source-serif-pro.out}/* src
            cp -r ${source-code-pro.out}/* src
            cp -r ${ibm-plex.out}/* src
            chmod -R u+w src
          '';
        snippets = pkgs.callPackage ./nix/snippets.nix {};
        snippetsLocal = with pkgs;
          writeScriptBin "gen-snippets"
          ''
    #!${stdenv.shell}
     set -ex
     cp -rf ${snippets.out}/* src
     chmod -R u+w src
    '';
      favicon = pkgs.callPackage ./nix/favicon.nix { };
      faviconLocal = with pkgs;
        writeScriptBin "gen-favicon"
            #!${stdenv.shell}
             set -ex
             cp -rf ${snippets.out}/* src
             chmod -R u+w src
          '';
        favicon = pkgs.callPackage ./nix/favicon.nix {};
        faviconLocal = with pkgs;
          writeScriptBin "gen-favicon"
          ''
    #!${stdenv.shell}
     cp -rf ${favicon.out}/* src
     chmod -R u+w src
    '';
      reveal = pkgs.callPackage ./nix/reveal.nix { };
      revealLocal = with pkgs;
        writeScriptBin "gen-reveal"
            #!${stdenv.shell}
             cp -rf ${favicon.out}/* src
             chmod -R u+w src
          '';
        reveal = pkgs.callPackage ./nix/reveal.nix {};
        revealLocal = with pkgs;
          writeScriptBin "gen-reveal"
          ''
    #!${stdenv.shell}
     cp -rf ${reveal.out}/* src
     chmod -R u+w src
    '';
      pygments = pkgs.python38Packages.pygments;
      build = pkgs.callPackage (import ./nix/derivation.nix) {};
      racketDependencies = (dream2nix.lib.makeFlakeOutputs {
        systems = [ system ];
        config.projectRoot = ./.;
        source = nix-filter.lib.filter {
          root = ./.;
          include = [ ./info.rkt ];
            #!${stdenv.shell}
             cp -rf ${reveal.out}/* src
             chmod -R u+w src
          '';
        pygments = pkgs.python38Packages.pygments;
        build = pkgs.callPackage (import ./nix/derivation.nix) {};
        racketDependencies =
          (dream2nix.lib.makeFlakeOutputs {
            systems = [system];
            config.projectRoot = ./.;
            source = nix-filter.lib.filter {
              root = ./.;
              include = [./info.rkt];
            };
            projects = ./projects.toml;
          })
          .packages
          .${system};
        pre-commit-check = pre-commit-hooks.lib.${system}.run {
          src = ./.;
          hooks = {
            alejandra.enable = true;
            shfmt.enable = true;
          };
        };
        projects = ./projects.toml;
      }).packages.${system};
    in {
      packages.default = build;
      devShells.resolve = pkgs.mkShell {
        buildInputs = [ racketDependencies.resolveImpure ];
      };
      devShells.default = pkgs.mkShell {
        COURSIER="${pkgs.coursier}/bin/cs";
        buildInputs = [
          pkgs.scala
          pkgs.coursier
          pkgs.tree
          serve
          fontLocal
          snippetsLocal
          faviconLocal
          revealLocal
          pygments
          racketDependencies.default
        ];
      };
    }
      in {
        packages.default = build;
        devShells.resolve = pkgs.mkShell {
          buildInputs = [racketDependencies.resolveImpure];
        };
        devShells.default = pkgs.mkShell {
          shellHook = pre-commit-check.shellHook;
          COURSIER = "${pkgs.coursier}/bin/cs";
          buildInputs = [
            pkgs.scala
            pkgs.coursier
            pkgs.tree
            serve
            fontLocal
            snippetsLocal
            faviconLocal
            revealLocal
            pygments
            racketDependencies.default
          ];
        };
      }
    );
}

M nix/derivation.nix => nix/derivation.nix +23 -24
@@ 4,35 4,34 @@
  coreutils,
  lib,
  nix-gitignore,
  symlinkJoin
}:
let
  symlinkJoin,
}: let
  # Generate the font files
  source-serif-pro = callPackage ./source-serif-pro.nix {};
  source-code-pro = callPackage ./source-code-pro.nix {};
  ibm-plex = callPackage ./ibm-plex.nix {};
  snippets = callPackage ./snippets.nix { };
  favicon = callPackage ./favicon.nix { };
  reveal = callPackage ./reveal.nix { };
  snippets = callPackage ./snippets.nix {};
  favicon = callPackage ./favicon.nix {};
  reveal = callPackage ./reveal.nix {};
  src = stdenv.mkDerivation {
      name = "src";
      nativeBuildInputs = [coreutils];
      src = nix-gitignore.gitignoreSource [] ./..;
      phases = "";
      dontConfigure = true;
      dontBuild = true;
      installPhase = ''
source $stdenv/setup
    name = "src";
    nativeBuildInputs = [coreutils];
    src = nix-gitignore.gitignoreSource [] ./..;
    phases = "";
    dontConfigure = true;
    dontBuild = true;
    installPhase = ''
      source $stdenv/setup

mkdir $out
ls -hal $src/src
cp -r $src/src/* $out
'';
    };
      mkdir $out
      ls -hal $src/src
      cp -r $src/src/* $out
    '';
  };
in
  # Combine the font files with the source
symlinkJoin {
  name = "fonts-and-src";
  meta.description = "Generates fonts and sources.";
  paths = [src source-serif-pro source-code-pro ibm-plex snippets favicon reveal];
}
  symlinkJoin {
    name = "fonts-and-src";
    meta.description = "Generates fonts and sources.";
    paths = [src source-serif-pro source-code-pro ibm-plex snippets favicon reveal];
  }

M nix/favicon.nix => nix/favicon.nix +4 -4
@@ 4,9 4,9 @@ stdenv.mkDerivation {
  src = ./../favicon.tar.gz;
  phases = "installPhase";
  installPhase = ''
  mkdir $out
  tar -xzf $src
  mv favicon/favicon.ico $out/favicon.ico
  mv favicon $out/favicon
    mkdir $out
    tar -xzf $src
    mv favicon/favicon.ico $out/favicon.ico
    mv favicon $out/favicon
  '';
}

M nix/ibm-plex.nix => nix/ibm-plex.nix +21 -17
@@ 1,17 1,21 @@
{ stdenv, fetchzip }:
let version = "6.0.0";
in stdenv.mkDerivation {
  name = "ibm-plex";
  meta.description = "IBM Plex font files and CSS of @font-face declarations.";
  src = fetchzip {
    url = "https://github.com/IBM/plex/releases/download/v${version}/Web.zip";
    sha256 = "1h80bbzybac3yyyhpjv9zzyhbka0ys0qflbmc0vn5yywpanif2r8";
  };
  phases = "unpackPhase installPhase";
  installPhase = ''
    mkdir $out
    cp -r IBM-Plex-Sans $out/IBM-Plex-Sans
    ls $out
    cp -r css $out/css
  '';
}
{
  stdenv,
  fetchzip,
}: let
  version = "6.0.0";
in
  stdenv.mkDerivation {
    name = "ibm-plex";
    meta.description = "IBM Plex font files and CSS of @font-face declarations.";
    src = fetchzip {
      url = "https://github.com/IBM/plex/releases/download/v${version}/Web.zip";
      sha256 = "1h80bbzybac3yyyhpjv9zzyhbka0ys0qflbmc0vn5yywpanif2r8";
    };
    phases = "unpackPhase installPhase";
    installPhase = ''
      mkdir $out
      cp -r IBM-Plex-Sans $out/IBM-Plex-Sans
      ls $out
      cp -r css $out/css
    '';
  }

M nix/python.nix => nix/python.nix +1 -6
@@ 1,7 1,2 @@
{
  pkgs ? import <nixpkgs> {}
}:
{pkgs ? import <nixpkgs> {}}:
pkgs.python38.withPackages (p: with p; [pygments])




M nix/render.bash => nix/render.bash +0 -1
@@ 7,7 7,6 @@ set -eux
cp -Lr result site
chmod -R u+w site # Change the ownership so that pollen can write to this directory


# Render the pages
raco pollen render site/snippets.ptree
raco pollen render site

M nix/reveal.nix => nix/reveal.nix +20 -17
@@ 1,17 1,20 @@
{ stdenv, fetchzip }:
let version = "4.5.0";
in stdenv.mkDerivation {
  name = "reveal";
  meta.description = "RevealJS distribution";
  src = fetchzip {
    url = "https://github.com/hakimel/reveal.js/archive/refs/tags/${version}.zip";
    sha256 = "sha256-9Q7aWgjAV37iJp6oYDz45e8J+RKwKY1Uvgg/BXwf5nQ=";
  };
  phases = "unpackPhase installPhase";
  installPhase = ''
    mkdir -p $out/reveal
    cp -r dist $out/reveal/dist
    cp -r plugin $out/reveal/plugin
  '';
}

{
  stdenv,
  fetchzip,
}: let
  version = "4.5.0";
in
  stdenv.mkDerivation {
    name = "reveal";
    meta.description = "RevealJS distribution";
    src = fetchzip {
      url = "https://github.com/hakimel/reveal.js/archive/refs/tags/${version}.zip";
      sha256 = "sha256-9Q7aWgjAV37iJp6oYDz45e8J+RKwKY1Uvgg/BXwf5nQ=";
    };
    phases = "unpackPhase installPhase";
    installPhase = ''
      mkdir -p $out/reveal
      cp -r dist $out/reveal/dist
      cp -r plugin $out/reveal/plugin
    '';
  }

M nix/snippets.bash => nix/snippets.bash +62 -64
@@ 4,86 4,84 @@ mkdir "$out"

# For each snippet.md file, run all of these

START_RX="\`\`\`scala.*"
END="\`\`\`"
START_RX='```scala.*'
END='```'

# Extracts the heading from a Markdown line 
# Extracts the heading from a Markdown line
function heading {
    local line="$1"
    sed -nE 's/# (.*)/\1/p' <<< "$line"
	local line="$1"
	sed -nE 's/# (.*)/\1/p' <<<"$line"
}

function output {
    local name="$1"
    local snippet="$2"
    local dir="$3"
    echo "Writing snippet file to $dir/$name.snippet ..."
    echo "$snippet" > "$dir/$name.snippet"
	local name="$1"
	local snippet="$2"
	local dir="$3"
	echo "Writing snippet file to $dir/$name.snippet ..."
	echo "$snippet" >"$dir/$name.snippet"
}

function reset {
 within_snippet=false
 name=""
 snippet=""
	within_snippet=false
	name=""
	snippet=""
}

function export_snippets {
    local file="$1"
    local dir=$(dirname "$file")
    local out_dir=$out${dir#$src}/snippets
    mkdir -p "$out_dir"
    local lines=()
    mapfile lines <"$file"
	local file="$1"
	local dir=$(dirname "$file")
	local out_dir=$out${dir#$src}/snippets
	mkdir -p "$out_dir"
	local lines=()
	mapfile lines <"$file"

    reset
    for line in "${lines[@]}";
    do
        trimmed_line=$(tr -d "\n" <<< "$line")
        maybe_heading=$(heading "$trimmed_line")
        if [ -n "$maybe_heading" ]; then
    	# We've started a new snippet
    	name="$maybe_heading"
        elif [[ "$trimmed_line" =~ $START_RX ]]; then
    	# This is the start of a new snippet
    	snippet=""
    	within_snippet=true
        elif [[ "$trimmed_line" == "$END" ]]; then
    	# We've reached the end of the snippet
    	if [ -n "$name" ] && [ -n "$snippet" ] ; then
    	    # Output the snippet
    	    output "$name" "$snippet" "$out_dir"
    	else
    	    if [ -n "$snippet" ]; then
    		echo -e "Error - the following snippet is missing a title:\n$snippet" >&2
    	    elif [ -n "$name" ]; then
    		echo -e "Error - the following title doesn't have a snippet: $name" >&2
    	    else
    		echo -e "Error extracting snippets." >&2
    	    fi
    	    exit 1
    	fi
    	# Reset the loop variables
    	reset
        elif [ "$within_snippet" = true ]; then
    	# Append the line to the snippet
    	snippet="$snippet$line"
        elif [ -n "$trimmed_line" ]; then
    	echo "Found a dangling line: $trimmed_line"
    	error 1
        fi
    done
	reset
	for line in "${lines[@]}"; do
		trimmed_line=$(tr -d "\n" <<<"$line")
		maybe_heading=$(heading "$trimmed_line")
		if [ -n "$maybe_heading" ]; then
			# We've started a new snippet
			name="$maybe_heading"
		elif [[ $trimmed_line =~ $START_RX ]]; then
			# This is the start of a new snippet
			snippet=""
			within_snippet=true
		elif [[ $trimmed_line == "$END" ]]; then
			# We've reached the end of the snippet
			if [ -n "$name" ] && [ -n "$snippet" ]; then
				# Output the snippet
				output "$name" "$snippet" "$out_dir"
			else
				if [ -n "$snippet" ]; then
					echo -e "Error - the following snippet is missing a title:\n$snippet" >&2
				elif [ -n "$name" ]; then
					echo -e "Error - the following title doesn't have a snippet: $name" >&2
				else
					echo -e "Error extracting snippets." >&2
				fi
				exit 1
			fi
			# Reset the loop variables
			reset
		elif [ "$within_snippet" = true ]; then
			# Append the line to the snippet
			snippet="$snippet$line"
		elif [ -n "$trimmed_line" ]; then
			echo "Found a dangling line: $trimmed_line"
			error 1
		fi
	done
}

export_all() {
    local files=$(find "$src" -name "snippets.out.md")
    local count=$(wc -l <<<"$files")
    echo "Found $count files matching 'snippets.out.md'."
    echo "$files"
	local files=$(find "$src" -name "snippets.out.md")
	local count=$(wc -l <<<"$files")
	echo "Found $count files matching 'snippets.out.md'."
	echo "$files"

    for file in $files ;
    do
        export_snippets $file
    done
	for file in $files; do
		export_snippets $file
	done
}

export_all

M nix/snippets.nix => nix/snippets.nix +5 -3
@@ 1,14 1,16 @@
# This assumes that mdoc has been run via the nix shell to generate the
# snippets.out.md files
{ stdenv, coreutils}:
{
  stdenv,
  coreutils,
}:
stdenv.mkDerivation {
  name = "snippets";
  meta.description = "Generates code snippets for blog posts.";
  builder =  ./snippets.bash ;
  builder = ./snippets.bash;
  nativeBuildInputs = [coreutils];
  src = ../src;
  phases = "";
  dontConfigure = true;
  dontBuild = true;
}


M nix/source-code-pro.nix => nix/source-code-pro.nix +4 -1
@@ 1,4 1,7 @@
{ stdenv, fetchzip }:
{
  stdenv,
  fetchzip,
}:
stdenv.mkDerivation {
  name = "source-code-pro";
  meta.description = "Source Code Pro font files and CSS of @font-face declarations.";

M nix/source-serif-pro.nix => nix/source-serif-pro.nix +23 -20
@@ 1,21 1,24 @@
{ stdenv, fetchzip }:
let
{
  stdenv,
  fetchzip,
}: let
  version = "3.001R";
in stdenv.mkDerivation {
  name = "source-serif-pro";
  meta.description = "Source Serif Pro font files and CSS of @font-face declarations.";
  src = fetchzip {
    url = "https://github.com/adobe-fonts/source-serif-pro/releases/download/${version}/source-serif-pro-${version}.zip";
    sha256 = "1z0pjvx0jpjwb8vzvc6l5gzlg0mqax4v9pizqcxx82l0ydlfh5bj";
  };
  phases = "unpackPhase installPhase";
  installPhase = ''
    mkdir $out
    cp -r OTF $out/OTF
    cp -r TTF $out/TTF
    cp -r VAR $out/VAR
    cp -r WOFF $out/WOFF
    cp -r WOFF2 $out/WOFF2
    cp *.css $out
  '';
}
in
  stdenv.mkDerivation {
    name = "source-serif-pro";
    meta.description = "Source Serif Pro font files and CSS of @font-face declarations.";
    src = fetchzip {
      url = "https://github.com/adobe-fonts/source-serif-pro/releases/download/${version}/source-serif-pro-${version}.zip";
      sha256 = "1z0pjvx0jpjwb8vzvc6l5gzlg0mqax4v9pizqcxx82l0ydlfh5bj";
    };
    phases = "unpackPhase installPhase";
    installPhase = ''
      mkdir $out
      cp -r OTF $out/OTF
      cp -r TTF $out/TTF
      cp -r VAR $out/VAR
      cp -r WOFF $out/WOFF
      cp -r WOFF2 $out/WOFF2
      cp *.css $out
    '';
  }

D src/assets/images/2023-06-07-scaladays-pierian-stream/rename.bash => src/assets/images/2023-06-07-scaladays-pierian-stream/rename.bash +0 -10
@@ 1,10 0,0 @@
#!/usr/bin/env bash

set -eux

for FILE in *.*;
do
    echo $FILE
    cp $FILE tmp/2023-06-07-scaladays-pierian-stream-$FILE
done