-*- mode: org -*-
#+TITLE:       configuration nix
#+DESCRIPTION: makefile for spine
#+FILETAGS:    :spine:build:tools:
#+AUTHOR:      Ralph Amissah
#+EMAIL:       [[mailto:ralph.amissah@gmail.com][ralph.amissah@gmail.com]]
#+COPYRIGHT:   Copyright (C) 2015 - 2021 Ralph Amissah
#+LANGUAGE:    en
#+STARTUP:     content hideblocks hidestars noindent entitiespretty
#+OPTIONS:     H:3 num:nil toc:t \n:nil @:t ::t |:t ^:nil _:nil -:t f:t *:t <:t
#+PROPERTY:    header-args  :exports code
#+PROPERTY:    header-args+ :noweb yes
#+PROPERTY:    header-args+ :eval no
#+PROPERTY:    header-args+ :results no
#+PROPERTY:    header-args+ :cache no
#+PROPERTY:    header-args+ :padline no
#+PROPERTY:    header-args+ :mkdirp yes

* nix :nix:
** NOTES
*** nix-shell

- default.nix

#+BEGIN_SRC sh
nix-shell
nix-build
#+END_SRC

- project.nix

#+BEGIN_SRC sh
nix-shell
nix-build project.nix
#+END_SRC

*** nix-shell --pure

- default.nix

#+BEGIN_SRC sh
nix-shell --pure
nix-build -I nixpkgs=/nixpkgs-ra/nixpkgs
#+END_SRC

- project.nix

#+BEGIN_SRC sh
nix-shell --pure
nix-build -I nixpkgs=/nixpkgs-ra/nixpkgs
#+END_SRC

#+BEGIN_SRC sh
nix build
nix build -f default.nix
nix build -f project.nix
nix build -f spine.nix
#+END_SRC

*** derivation .drv

#+BEGIN_SRC sh
nix show-derivation /nix/store/q7n14bm8j5vzm62qaraczdb4bpyf59vv-spine-0.11.1.drv
#+END_SRC

** spine

- default.nix
- shell.nix

*** envrc :envrc:
**** .envrc

#+HEADER: :tangle ../.envrc
#+BEGIN_SRC sh
NIX_ENFORCE_PURITY=0
if ! has nix_direnv_version || ! nix_direnv_version 1.4.0; then
# https://github.com/nix-community/nix-direnv
  source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/1.4.0/direnvrc" "sha256-4XfVDjv75eHMWN4G725VW7BoOV4Vl3vAabK4YXIfPyE="
fi
if [ -e .envrc-local ]; then # source an additional user-specific .envrc in ./.envrc-local
  source .envrc-local
fi
#+END_SRC

- lorri?

#+HEADER: :NO-tangle ../.envrc
#+BEGIN_SRC sh
if type lorri &>/dev/null; then
  echo "direnv: using lorri from PATH ($(type -p lorri))"
  # eval "$(lorri direnv)"
else # fallback prevent bootstrapping problems by using direnv's builtin nix support
  use nix
  NIX_ENFORCE_PURITY=0
fi
if [ -e .envrc-local ]; then # source an additional user-specific .envrc in ./.envrc-local
  source .envrc-local
fi
#+END_SRC

- enable flakes

#+HEADER: :NO-tangle ../.envrc
#+BEGIN_SRC sh
if [ -f flake.lock ] && [ -f flake.nix ]; then
    # reload when these files change
    watch_file flake.nix
    watch_file flake.lock
    # load the flake devShell
    if [ ! -d $(direnv_layout_dir) ]; then
        mkdir $(direnv_layout_dir)
    fi
    eval "$(nix --experimental-features 'nix-command flakes' print-dev-env --profile "$(direnv_layout_dir)/flake-profile")"
else
    # fall back to using direnv's builtin nix support
    # to prevent bootstrapping problems.
  #  use nix
  if type lorri &>/dev/null; then
      echo "direnv: using lorri from PATH ($(type -p lorri))"
      eval "$(lorri direnv)"
  else
      # fall back to using direnv's builtin nix support
      # to prevent bootstrapping problems.
      use nix
      NIX_ENFORCE_PURITY=0
  fi
  # source an additional user-specific .envrc in ./.envrc-local
  if [ -e .envrc-local ]; then
     source .envrc-local
  fi
fi
#+END_SRC

**** .envrc-local CHECK MODIFY

- bespoke modify appropriately and generate if needed

#+HEADER: :tangle ../.envrc-local_
#+BEGIN_SRC sh
export NIX_PATH=<<nix_path_channel>>
#export NIX_PATH=<<nixpkgs_path_local>>
# reload when these files change
# watch_file flake.nix
# watch_file flake.lock
## load the flake devShell
# eval "$(nix print-dev-env)"
# echo $NIX_BUILD_TOP
export SpineVER=$(git describe --long --tags | sed 's/^[ a-z_-]\+\([0-9.]\+\)/\1/;s/\([^-]*-g\)/r\1/;s/-/./g')
export SpineSRC=<<project_path_local_src>>
export SpineBIN=<<project_path_local_bin>>
export SpineDOC=<<project_path_local_doc>>
export SpinePOD=$SpineDOC/markup/pod
export SpineOUTversioned=<<project_path_local_out>>
export SpineOUT=<<project_path_local_out_static>>
export SpineDBpath=<<project_path_sqlite>>

echo '-*- mode: org -*-

,* nixpkgs path?

  # eval "$(nix print-dev-env)"
' > nixNote_.org

echo "  <nixpkgs> == `nix-instantiate --find-file nixpkgs`" >> nixNote_.org

echo '
,* nix build and show derivation

,#+BEGIN_SRC sh
nix-shell --pure

nix-build
nix build -f default.nix
nix shell -f default.nix
nix-instantiate | nix-build
nix build `nix-instantiate`

nix develop

nix-instantiate | nix show-derivation | jq
nix-instantiate | nix show-derivation --recursive | jq

nix search --json 2>/dev/null |jq
,#+END_SRC

,* version and build info

,#+BEGIN_SRC sh' >> nixNote_.org

echo 'spine version (git) == $SpineVER' >> nixNote_.org
echo "spine version (git) == $SpineVER" >> nixNote_.org
echo 'nix-instantiate == `nix-instantiate`' >> nixNote_.org
echo "nix-instantiate == `nix-instantiate`" >> nixNote_.org

echo "#+END_SRC

,* initialised shell variables

,#+BEGIN_SRC sh
SpineSRC=$SpineSRC
SpineDOC=$SpineDOC
SpinePOD=$SpinePOD
SpineOUTversioned=$SpineOUTversioned
SpineOUT=$SpineOUT
,#+END_SRC
" >> nixNote_.org

echo '* spine run instruction examples
,** parallelized tasks
,*** doc source

,#+BEGIN_SRC sh
$SpineBIN/spine --very-verbose --pod --source --output="$SpineOUTversioned" $SpinePOD/*
,#+END_SRC

,*** html & epub output

,#+BEGIN_SRC sh
$SpineBIN/spine --very-verbose --html --epub --output="$SpineOUTversioned" $SpinePOD/*
,#+END_SRC

,*** sqlite db for each document - populate each db

,#+BEGIN_SRC sh
$SpineBIN/spine --very-verbose --sqlite-discrete --output="$SpineOUTversioned" $SpinePOD/*
,#+END_SRC

,*** doc source; html, epub; sqlite outputs

,#+BEGIN_SRC sh
$SpineBIN/spine --verbose --pod --html --epub --sqlite-discrete --output="$SpineOUTversioned" $SpinePOD/*
,#+END_SRC

,*** curate (authors topics)

,#+BEGIN_SRC sh
$SpineBIN/spine --very-verbose --curate --output="$SpineOUTversioned" $SpinePOD/*
,#+END_SRC

,*** html, curate

,#+BEGIN_SRC sh
$SpineBIN/spine --verbose --dark --html --html-link-curate --curate --output="$SpineOUTversioned" $SpinePOD/*
$SpineBIN/spine --very-verbose --html --html-link-curate --curate --output="$SpineOUTversioned" $SpinePOD/*
,#+END_SRC

,*** composite command: source pod, html, epub, curate, sqlite

,#+BEGIN_SRC sh
$SpineBIN/spine --verbose --dark --pod --epub --html --html-link-curate --curate --sqlite-discrete --output="$SpineOUTversioned" $SpinePOD/*
,#+END_SRC

,** sequential tasks
,*** sqlite db (shared) - create db

,#+BEGIN_SRC sh
$SpineBIN/spine --very-verbose --sqlite-db-create --output="$SpineOUTversioned"
,#+END_SRC

,*** sqlite db (shared) - populate db

,#+BEGIN_SRC sh
$SpineBIN/spine --very-verbose --sqlite-update --output="$SpineOUTversioned" $SpineDOC/spine-markup-samples/markup/pod/*
,#+END_SRC

,*** sqlite db (shared) - drop db

,#+BEGIN_SRC sh
$SpineBIN/spine --very-verbose --sqlite-db-drop --output="$SpineOUTversioned"
,#+END_SRC

,*** sqlite db (shared) - create & populate db (single step)

,#+BEGIN_SRC sh
$SpineBIN/spine --very-verbose --sqlite-db-create --sqlite-update --output="$SpineOUTversioned" $SpinePOD/*
,#+END_SRC

,*** composite command: source pod, html, epub, curate, sqlite

,#+BEGIN_SRC sh
$SpineBIN/spine --verbose --no-parallel --dark --pod --epub --html --html-link-curate --curate --sqlite-discrete --output="$SpineOUTversioned" $SpinePOD/*
,#+END_SRC

,** config [./pod/].dr/config_local_site

,#+BEGIN_SRC sh
cat $SpinePOD/.dr/config_local_site
$SpineBIN/spine --show-config $SpinePOD
$SpineBIN/spine --show-config --output="$SpineOUTversioned" $SpinePOD
,#+END_SRC

,** cgi operations (output to $SpineOUT /var/www)

,#+BEGIN_SRC sh
$SpineBIN/spine --very-verbose --sqlite-db-create --output="$SpineOUT" $SpinePOD/*

$SpineBIN/spine -v --cgi-search-form-codegen --output=$SpineOUT $SpinePOD/*

$SpineBIN/spine -v --show-config --config=$SpinePOD/.dr

$SpineBIN/spine --html $SpinePOD/*


$SpineBIN/spine -v --cgi-search-form-codegen --config=$SpinePOD/.dr/config_local_site
,#+END_SRC

,*** generate html linked to search form

,#+BEGIN_SRC sh
$SpineBIN/spine -v --html --html-link-search --html-link-curate --curate  --output=$SpineOUT $SpinePOD/*
,#+END_SRC

,*** create or re-create sql db (--sqlite-db-create or --sqlite-db-recreate)

,#+BEGIN_SRC sh
$SpineBIN/spine -v --sqlite-db-create --sqlite-db-filename="<<spine_search_db>>" --sqlite-db-path="$SpineDBpath"
$SpineBIN/spine -v --sqlite-db-recreate --sqlite-db-filename="<<spine_search_db>>" --sqlite-db-path="$SpineDBpath"
,#+END_SRC

,*** populate sqlite db

,#+BEGIN_SRC sh
$SpineBIN/spine -v --sqlite-update --sqlite-db-filename="<<spine_search_db>>" --output=$SpineOUT $SpinePOD/*
,#+END_SRC

,*** generate html (linked to search form), sql output, curate COMPOSITE

,#+BEGIN_SRC sh
$SpineBIN/spine -v --html --html-link-search --html-link-curate --curate --sqlite-update --sqlite-db-filename="<<spine_search_db>>" --cgi-sqlite-search-filename="<<spine_search_cgi>>" --sqlite-db-path="$SpineDBpath" --output="$SpineOUT" $SpinePOD/*
$SpineBIN/spine --epub --html --html-link-search --html-link-curate --curate --sqlite-update --sqlite-db-filename="spine.search.db" --cgi-sqlite-search-filename="spine_search" --cgi-url-action="https://sisudoc.org/spine_search" --ouput="$SpineOUT" $SpinePOD/*
,#+END_SRC

,*** generate html (linked to search form), sql output, curate COMPOSITE with resource configuration

if names and paths are configured in resource configuration file, e.g. $SpinePOD/.rc/config_local_site

,#+BEGIN_SRC sh
$SpineBIN/spine -v --html --html-link-search --html-link-curate --curate --sqlite-update $SpinePOD/*
,#+END_SRC

,#+BEGIN_SRC yaml
# sample resource configuration file ( $SpinePOD/.rc/config_local_site )
output:
  path:                        "/srv/www/spine"
default:
  language:                    "en"
  papersize:                   "a4"
  text_wrap:                   "80"
  digest:                      "sha256"
webserv:
  http:                        "http"
  domain:                      "localhost"
  data_http:                   "http"
  data_domain:                 "localhost"
  data_root_url:               "https://sisudoc.org"
  data_root_path:              "/srv/www/spine"
  images_root_part:            "image"
  cgi_search_form_title:       "≅ SiSU Spine search"
  cgi_http:                    "https"
  cgi_domain:                  "sisudoc.org"
  cgi_bin_url:                 "http://sisudoc.org/cgi-bin"
  cgi_bin_part:                "cgi-bin"
  cgi_bin_path:                "/var/www/cgi/cgi-bin"
  cgi_search_script:           "<<spine_search_cgi>>"
  cgi_action:                  "https://sisudoc.org/spine_search"
  db_sqlite_filename:          "<<spine_search_db>>"
  db_sqlite_path:              "/var/www/sqlite"
,#+END_SRC

,*** make search form

,#+BEGIN_SRC sh
$SpineBIN/spine -v --cgi-search-form-codegen --config=$SpinePOD/.dr/config_local_site
,#+END_SRC

,*** latex

,#+BEGIN_SRC sh
$SpineBIN/spine --latex --serial --output="$SpineOUT" $SpinePOD/*
ls $SpineOutstatic/latex/*.tex
,#+END_SRC
' >> nixNote_.org

#cat nixNote_.org

#echo "emacs nixNote_.org"
#echo "cat nixNote_.org"
#+END_SRC

*** flake :flake:

- flake.nix
    /nixpkgs-ra/nixpkgs
    ./shell.nix
  - shell.nix
      ./pkgs/shell-pkgs.nix
    - pkgs/shell-pkgs.nix
  - default.nix
     ./nix/dub.selections.nix #
    - dub.selections.nix

nix develop

nix flake update

#+HEADER: :tangle ../flake.nix
#+BEGIN_SRC nix
{
  description = "a sisu like document parser";
  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    nixpkgs.url = "<<nixpkgs_url>>";
  };
  outputs = { self, nixpkgs, flake-utils }:
  let
    pkgs = nixpkgs.legacyPackages.x86_64-linux;
  in {
    packages.x86_64-linux.spine = pkgs.stdenv.mkDerivation {
      name = "spine";
      inherit self;
      src = self;
      shell = ./shell.nix;
      installPhase = ''
         install -m755 spine $out/bin/spine
      '';
    };
    defaultPackage.x86_64-linux = self.packages.x86_64-linux.spine;
  };
}
#+END_SRC

#+BEGIN_SRC nix
{
  description = "a sisu like document parser";
  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    nixpkgs.url = "<<nixpkgs_url>>";
    d2sqlite3 = {
      url    = "github:dlang-community/d2sqlite3";
      flake  = false;
    };
    tinyendian = {
      url    = "github:kiith-sa/tinyendian";
      flake  = false;
    };
    dyaml = {
      url    = "github:dlang-community/D-YAML";
      flake  = false;
    };
    imageformats = {
      url    = "github:lgvz/imageformats";
      flake  = false;
    };
  };
  outputs = { self, d2sqlite3, tinyendian, dyaml, imageformats, nixpkgs, flake-utils }:
  let
    pkgs = nixpkgs.legacyPackages.x86_64-linux;
  in {
    packages.x86_64-linux.spine = pkgs.stdenv.mkDerivation {
      name = "spine";
      inherit self;
      src = self;
      shell = ./shell.nix;
      installPhase = ''
         install -m755 spine $out/bin/spine
      '';
    };
    defaultPackage.x86_64-linux = self.packages.x86_64-linux.spine;
  };
}
#+END_SRC

#+HEADER: :NO-tangle ../flake.nix
#+BEGIN_SRC nix
{
  description = "a sisu like document parser";
  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    nixpkgs.url = "<<nixpkgs_url>>";
    # pkgs /nixpkgs-ra/nixpkgs {}
    #spine.url = "/grotto-ra/repo/git.repo/projects/project-spine/doc-reform";
    #spine.url = "./.";
  };
  outputs = { self, nixpkgs, flake-utils }:
    #flake-utils.lib.eachSystem [ "x86_64-linux" "defaultPackage.x86_64-linux" "packages.x86_64-linux.defaultPackage.x86_64-linux" ] (system:
    flake-utils.lib.eachDefaultSystem (system:
      let
        #pkgs = ${system};
        pkgs = nixpkgs.legacyPackages.${system};
        # project = pkgs.spine.project' {
        #   src = ./.;
        #   compiler-nix-name = "ldc";
        # };
      in { #project.flake {} // {
        #devShell = project.shellFor {
        #  (import ./shell.nix self { inherit pkgs; });
        #};
        devShell = import ./default.nix self { inherit pkgs; };
      }
    );
}
#+END_SRC

*** shell.nix :shell:
**** NOTES

  nix-shell

  shell.nix --pure
  shell.nix --pure -I .envrc

  nix-shell --pure -I nixpkgs=/nixpkgs-ra/nixpkgs
  nix-shell --pure -p "with import /nixpkgs-ra/nixpkgs {}; ldc"
  nix-shell --pure -p "with import /nixpkgs-ra/nixpkgs {}; [dub ldc]"

  shell.nix direnv: export +IN_NIX_SHELL

  nix-shell -p nixFlakes
  nix-shell -p nixFlakes --pure
  nix-shell -p nixFlakes --pure -p "with import /nixpkgs-ra/nixpkgs {}; [dub ldc]"

  shell.nix -I .envrc
  shell.nix

  nix develop

  nix-build
  nix-build -I nixpkgs=<provide local nix path>
  nix-build -I .envrc

  nix build
  nix build -f default.nix && noti
  nix build -f default.nix && ./result/bin/spine -v && noti -t "spine build" -m "see ./result/bin/spine"
  nix build -f spine.nix && ./result/bin/spine -v && noti -t "spine build" -m "see ./result/bin/spine"
  nix build -f project.nix
  nix build -f spine.nix

  nix-shell shell.nix --pure
  nix build -f default.nix
  ./result/bin/spine

**** tangle

#+HEADER: :tangle ../shell.nix
#+HEADER: :tangle-mode (identity #o755)
#+HEADER: :shebang "#!/usr/bin/env -S nix-shell --pure"
#+BEGIN_SRC nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  buildInputs = with pkgs; [
    <<shell_packages_nix_related>>
    <<shell_packages_d_build_related>>
    <<shell_packages_candy>>
    # <<shell_packages_search_related_sqlite>>
    # <<shell_packages_pdf_latex_related>>
    # <<shell_packages_xml_and_epub_related>>
  ];
  shellHook = ''
    if [[ -e ".envrc" ]]; then
      source .envrc
    fi
    eval "$(starship init bash)"
  '';
}
#+END_SRC

**** parts
***** packages nix related

#+NAME: shell_packages_nix_related
#+BEGIN_SRC nix
# nix_related
nixFlakes
nix-prefetch-git
validatePkgConfig
jq
git
#+END_SRC

***** packages d build related

#+NAME: shell_packages_d_build_related
#+BEGIN_SRC nix
# d_build_related
rund
dub
ldc
#meson
#+END_SRC

***** packages candy

#+NAME: shell_packages_candy
#+BEGIN_SRC nix
# candy
starship
#+END_SRC

***** packages search sqlite related

#+NAME: shell_packages_search_related_sqlite
#+BEGIN_SRC nix
# search_sqlite_related
# search related
sqlite
#+END_SRC

***** packages pdf latex related

#+NAME: shell_packages_pdf_latex_related
#+BEGIN_SRC nix
# pdf_latex_related
source-sans-pro
source-serif-pro
source-code-pro
texlive.combined.scheme-full
#+END_SRC

***** packages xml epub related

#+NAME: shell_packages_xml_and_epub_related
#+BEGIN_SRC nix
# xml_and_epub_related
libxml2
html-tidy
xmlstarlet
epubcheck
ebook_tools
epr
sigil
calibre # (ebook-viewer)
foliate
#+END_SRC

**** misc

#+HEADER: :NO-tangle ../shell.nix
#+HEADER: :tangle-mode (identity #o755)
#+HEADER: :shebang "#!/usr/bin/env -S nix-shell"
#+BEGIN_SRC nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  buildInputs = with pkgs; [
    (import ./nix/pkglst/shell-pkgs.nix { inherit pkgs; })
  ];
  buildPhase = "nix build -f default.nix";
  shellHook = ''
    echo "built spine @ ./result/bin/spine"
    if [[ -e ".envrc" ]]; then
      source .envrc
    fi
    nix-instantiate | nix show-derivation | jq
  '';
}
#+END_SRC

*** default.nix :default:

- default.nix -I nixpkgs=<provide local nix path>
  e.g. default.nix -I nixpkgs=/nixpkgs-ra/nixpkgs

- nix-build -I nixpkgs=<provide local nix path>
  e.g. nix-build -I nixpkgs=/nixpkgs-ra/nixpkgs

#+BEGIN_SRC sh
nix-build -I nixpkgs=/nixpkgs-ra/nixpkgs
nix-build -I .envrc-local
nix-build -I .envrc
default.nix -I .envrc
default.nix

nix build
nix build -f default.nix
nix build -f project.nix
nix build -f spine.nix
#+END_SRC

#+HEADER: :tangle ../default.nix
#+HEADER: :tangle-mode (identity #o755)
#+HEADER: :shebang "#!/usr/bin/env -S nix-build"
#+BEGIN_SRC nix
{ pkgs ? import <nixpkgs> {},
  stdenv ? pkgs.stdenv,
  lib ? pkgs.lib,
  ldc ? null,
  dcompiler ? pkgs.ldc,
  dub ? pkgs.dub
}:
assert dcompiler != null;
with (
  assert dcompiler != null;
  with lib;
  let
    # Filter function to remove the .dub package folder from src
    filterDub = name: type: let baseName = baseNameOf (toString name); in ! (
      type == "directory" && baseName == ".dub"
    );
    targetOf = package: "${package.targetPath or "."}/${package.targetName or package.name}";
    # Remove reference to build tools and library sources
    disallowedReferences = deps: [ dcompiler dub ];
    removeExpr = refs: ''remove-references-to ${lib.concatMapStrings (ref: " -t ${ref}") refs}'';
  in {
    mkDubDerivation = lib.makeOverridable ({
      src,
      nativeBuildInputs ? [],
      dubJSON ? src + "/dub.json",
      passthru ? {},
      package ? lib.importJSON dubJSON,
      ...
    } @ attrs: stdenv.mkDerivation (attrs // {
      pname = package.name;
      nativeBuildInputs = [ dcompiler dub pkgs.removeReferencesTo ] ++ nativeBuildInputs;
      disallowedReferences = disallowedReferences deps;
      passthru = passthru // {
        inherit dub dcompiler pkgs;
      };
      src = lib.cleanSourceWith {
        filter = filterDub;
        src = lib.cleanSource src;
      };
      preFixup = ''
        find $out/bin -type f -exec ${removeExpr (disallowedReferences deps)} '{}' + || true
      '';
      buildPhase = ''
        runHook preBuild
        export HOME=$PWD
        for dc_ in dmd ldmd2 gdmd; do
          echo "- check for D compiler $dc_"
          dc=$(type -P $dc_ || echo "")
          if [ ! "$dc" == "" ]; then
            break
          fi
        done
        if [ "$dc" == "" ]; then
          exit "Error: could not find D compiler"
        fi
        echo "$dc_ used as D compiler to build $pname"
        dub build --compiler=$dc --build=release --combined --skip-registry=all
        runHook postBuild
      '';
      checkPhase = ''
        runHook preCheck
        export HOME=$PWD
        dub test --combined --skip-registry=all
        runHook postCheck
      '';
      installPhase = ''
        runHook preInstall
        mkdir -p $out/bin
        cp -r "${targetOf package}" $out/bin
        runHook postInstall
      '';
      meta = lib.optionalAttrs (package ? description) {
        description = package.description;
      } // attrs.meta or {};
    } // lib.optionalAttrs (!(attrs ? version)) {
      # Use name from dub.json, unless pname and version are specified
      name = package.name;
    }));
  }
);
mkDubDerivation rec {
  name = "spine-${version}";
  version = "<<spine_version_set>>";
  src = ./.;
  buildInputs = with pkgs; [
    nixFlakes
    rund
    dub
    ldc
    sqlite
  ];
  # buildPhase = [ ];
  installPhase = ''
    install -m755 -D spine $out/bin/spine
    echo "built $out/bin/spine"
  '';
  <<nix_project_meta>>
}
#+END_SRC

- unused
  - installPhase

#+BEGIN_SRC txt
installPhase = ''
  mkdir -p $out/bin
  cp spine $out/bin
  chmod +x $out/bin/spine
'';
#+END_SRC

*** project meta

#+NAME: nix_project_meta
#+BEGIN_SRC nix
meta = with pkgs.lib; {
  homepage    = https://sisudoc.org;
  description = "a sisu like document parser";
  license     = licenses.agpl3Plus;
  platforms   = platforms.linux;
  maintainers = [ RalphAmissah ];
};
#+END_SRC

*** dub.selections.json

#+HEADER: :NO-tangle ../dub.selections.json
#+BEGIN_SRC nix
{
	"fileVersion": 1,
	"versions": {
		"d2sqlite3": "0.19.1",
		"dyaml": "0.8.3",
		"imageformats": "7.0.2",
		"tinyendian": "0.2.0"
	}
}
#+END_SRC

*** dub.selections.nix

#+HEADER: :NO-tangle ../nix/dub.selections.nix
#+BEGIN_SRC nix
# This file was generated by https://github.com/lionello/dub2nix v0.2.3
[ {
  fetch = {
    type = "git";
    url = "https://github.com/dlang-community/d2sqlite3.git";
    rev = "v0.19.1";
    sha256 = "0rnsgla6xyr8r34knf7v6dwhacra96q1b5rhxcz9246inwhvrk5k";
    fetchSubmodules = false;
    date = "2020-07-21T12:32:51+02:00";
    deepClone = false;
    leaveDotGit = false;
    path = "/nix/store/hsi8xvl15w6fwlqvs042m1z5i88yc72i-d2sqlite3";
  };
} {
  fetch = {
    type = "git";
    url = "https://github.com/kiith-sa/tinyendian.git";
    rev = "v0.2.0";
    sha256 = "086gf5aga52wr5rj2paq54daj8lafn980x77b706vvvqaz2mlis8";
    fetchSubmodules = false;
    date = "2018-06-10T11:04:28+02:00";
    deepClone = false;
    leaveDotGit = false;
    path = "/nix/store/9c7fsmi5am84j6dq2mp3va306x3ay291-tinyendian";
  };
} {
  fetch = {
    type = "git";
    url = "https://github.com/kiith-sa/D-YAML.git";
    rev = "v0.8.3";
    sha256 = "13wy304xjbwkpgg7ilql1lkxkm83s87jm59ffnrg26slp7cx149q";
    fetchSubmodules = false;
    date = "2020-09-19T23:46:57+02:00";
    deepClone = false;
    leaveDotGit = false;
    path = "/nix/store/3i8i56lkmw2xq3lxr5h66v909waq2mqg-D-YAML";
  };
} {
  fetch = {
    type = "git";
    url = "https://github.com/lgvz/imageformats.git";
    rev = "v7.0.2";
    sha256 = "1mfbsmi4fs1xny4zqs6jyr04d5f4h03r9f6jadvkdqj5kd1k0ws7";
    fetchSubmodules = false;
    date = "2019-10-10T07:54:45+03:00";
    deepClone = false;
    leaveDotGit = false;
    path = "/nix/store/wn554pn21nzmpvw2hs7hvv9v9y0sgarg-imageformats";
  };
} ]
#+END_SRC

*** dub2nix & shared pkgs SHARED
**** dub2nix with pkgs shared

#+NAME: nix_with_pkgs
#+BEGIN_SRC nix
with pkgs; [
  <<nix_shell_with_pkgs_list>>
]
#+END_SRC

**** with pkgs list

#+NAME: nix_shell_with_pkgs_list
#+BEGIN_SRC nix
nixFlakes
rund
dub
ldc
sqlite
nix-prefetch-git
validatePkgConfig
jq
git
#+END_SRC

** spine search cgi (in ./sundry)
*** envrc :envrc:
**** .envrc

#+HEADER: :tangle "../sundry/spine_search_cgi/.envrc"
#+BEGIN_SRC sh
NIX_ENFORCE_PURITY=0
if ! has nix_direnv_version || ! nix_direnv_version 1.4.0; then
# https://github.com/nix-community/nix-direnv
  source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/1.4.0/direnvrc" "sha256-4XfVDjv75eHMWN4G725VW7BoOV4Vl3vAabK4YXIfPyE="
fi
if [ -e .envrc-local ]; then # source an additional user-specific .envrc in ./.envrc-local
  source .envrc-local
fi
#+END_SRC

**** .envrc-local

#+HEADER: :tangle "../sundry/spine_search_cgi/.envrc-local_"
#+BEGIN_SRC sh
export NIX_PATH=/nix/var/nix/profiles/per-user/root/channels/nixos
#export NIX_PATH=nixpkgs=/nixpkgs-ra/nixpkgs
# reload when these files change
# watch_file flake.nix
# watch_file flake.lock
## load the flake devShell
# eval "$(nix print-dev-env)"
# echo $NIX_BUILD_TOP
export SpineVER=$(git describe --long --tags | sed 's/^[ a-z_-]\+\([0-9.]\+\)/\1/;s/\([^-]*-g\)/r\1/;s/-/./g')
export SpineSRC=<<project_path_local_src>>
export SpineBIN=<<project_path_local_bin>>
export SpineDOC=<<project_path_local_doc>>
export SpinePOD=$SpineDOC/markup/pod
#export SpineOUTversioned=<<project_path_local_out>>
export SpineOUT=<<project_path_local_out_static>>
export SpineDBpath=<<project_path_sqlite>>
export SpineCgiBIN=<<project_path_cgi_bin>>

echo '-*- mode: org -*-

,* nixpkgs path?

  # eval "$(nix print-dev-env)"
' > nixNote_.org

echo "  <nixpkgs> == `nix-instantiate --find-file nixpkgs`" >> nixNote_.org

echo '
,* nix build and show derivation

,#+BEGIN_SRC sh
nix-shell --pure

nix-build
nix build -f default.nix
nix shell -f default.nix
nix-instantiate | nix-build
nix build `nix-instantiate`

nix develop

nix-instantiate | nix show-derivation | jq
nix-instantiate | nix show-derivation --recursive | jq

nix search --json 2>/dev/null |jq
,#+END_SRC

,* version and build info

,#+BEGIN_SRC sh' >> nixNote_.org

echo 'spine version (git) == $SpineVER' >> nixNote_.org
echo "spine version (git) == $SpineVER" >> nixNote_.org
echo 'nix-instantiate == `nix-instantiate`' >> nixNote_.org
echo "nix-instantiate == `nix-instantiate`" >> nixNote_.org

echo "#+END_SRC

,* initialised shell variables

,#+BEGIN_SRC sh
SpineSRC=$SpineSRC
SpineBIN=$SpineBIN
SpineDOC=$SpineDOC
SpinePOD=$SpinePOD
#SpineOUTversioned=$SpineOUTversioned
SpineOUT=$SpineOUT
SpineCgiBIN=$SpineCgiBIN
,#+END_SRC
" >> nixNote_.org

echo '* cgi form spine_search nix build and copy to spine-search

,#+BEGIN_SRC sh
nix-build && sudo cp -vi result/share/cgi-bin/spine_search $SpineCgiBIN/.
,#+END_SRC

,* spine run instruction examples
,** cgi operations (output to $SpineOUT)
,*** configuration

,#+BEGIN_SRC sh
$SpineBIN/spine -v --show-config --config=$SpinePOD/.dr
,#+END_SRC

,*** generate html (linked to search form & curate)

,#+BEGIN_SRC sh
$SpineBIN/spine -v --html --html-link-search --html-link-curate --sqlite-db-filename="<<spine_search_db>>" --cgi-sqlite-search-filename="<<spine_search_cgi>>"--output=$SpineOUT $SpinePOD/*
,#+END_SRC

,*** generate sql output

,#+BEGIN_SRC sh
SpineBIN/spine -v --sqlite-update --sqlite-db-filename="<<spine_search_db>>" --sqlite-db-path="$SpineDBpath"
,#+END_SRC

,*** generate curate

,#+BEGIN_SRC sh
$SpineBIN/spine -v --curate --output=$SpineOUT $SpinePOD/*
$SpineBIN/spine -v --html --html-link-curate --curate  --output=$SpineOUT $SpinePOD/*
,#+END_SRC

,*** create or re-create sql db (--sqlite-db-create or --sqlite-db-recreate)

,#+BEGIN_SRC sh
$SpineBIN/spine -v --sqlite-db-recreate --sqlite-db-filename="<<spine_search_db>>" --sqlite-db-path="$SpineDBpath"
,#+END_SRC

,*** generate html (linked to search form), sql output, curate

,#+BEGIN_SRC sh
$SpineBIN/spine -v --html --html-link-search --html-link-curate --curate --sqlite-db-filename="<<spine_search_db>>" --cgi-sqlite-search-filename="<<spine_search_cgi>>" --sqlite-update --sqlite-db-path="$SpineDBpath" --output="$SpineOUT" $SpinePOD/*
#if names and paths are configured in resource configuration file, e.g. $SpinePOD/.rc/config_local_site
$SpineBIN/spine -v --html --html-link-search --html-link-curate --curate --sqlite-update $SpinePOD/*
,#+END_SRC

,*** make search form

,#+BEGIN_SRC sh
$SpineBIN/spine -v --cgi-search-form-codegen --config=$SpinePOD/.dr/config_local_site
#$SpineBIN/spine -v --cgi-search-form-codegen --output=$SpineOUT $SpinePOD/*
,#+END_SRC
' >> nixNote_.org

#cat nixNote_.org

#echo "emacs nixNote_.org"
#echo "cat nixNote_.org"
#+END_SRC

*** flake :flake:

- flake.nix

nix develop

nix flake update

#+HEADER: :tangle "../sundry/spine_search_cgi/flake.nix"
#+BEGIN_SRC nix
{
  description = "a sisu like document parser search form";
  inputs = {
    flake-utils.url = "github:numtide/flake-utils";
    nixpkgs.url = "github:nixos/nixpkgs";
  };
  outputs = { self, nixpkgs, flake-utils }:
  let
    pkgs = nixpkgs.legacyPackages.x86_64-linux;
  in {
    packages.x86_64-linux.spine = pkgs.stdenv.mkDerivation {
      name = "spine_search";
      inherit self;
      src = self;
      shell = ./shell.nix;
      installPhase = ''
        install -m755 -D spine_search $out/share/cgi-bin/spine_search
      '';
    };
    defaultPackage.x86_64-linux = self.packages.x86_64-linux.spine;
  };
}
#+END_SRC

*** shell.nix :shell:

#+HEADER: :tangle "../sundry/spine_search_cgi/shell.nix"
#+HEADER: :tangle-mode (identity #o755)
#+HEADER: :shebang "#!/usr/bin/env -S nix-shell --pure"
#+BEGIN_SRC nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  buildInputs = with pkgs; [
    <<shell_packages_nix_related>>
    <<shell_packages_d_build_related>>
    <<shell_packages_search_related_sqlite>>
    <<shell_packages_candy>>
  ];
  shellHook = ''
    if [[ -e ".envrc" ]]; then
      source .envrc
    fi
    eval "$(starship init bash)"
  '';
}
#+END_SRC

*** default.nix :default:

#+HEADER: :tangle "../sundry/spine_search_cgi/default.nix"
#+HEADER: :tangle-mode (identity #o755)
#+HEADER: :shebang "#!/usr/bin/env -S nix-build"
#+BEGIN_SRC nix
{ pkgs ? import <nixpkgs> {},
  stdenv ? pkgs.stdenv,
  lib ? pkgs.lib,
  ldc ? null,
  dcompiler ? pkgs.ldc,
  dub ? pkgs.dub
}:
assert dcompiler != null;
with (
  assert dcompiler != null;
  with lib;
  let
    # Filter function to remove the .dub package folder from src
    filterDub = name: type: let baseName = baseNameOf (toString name); in ! (
      type == "directory" && baseName == ".dub"
    );
    targetOf = package: "${package.targetPath or "."}/${package.targetName or package.name}";
    # Remove reference to build tools and library sources
    disallowedReferences = deps: [ dcompiler dub ];
    removeExpr = refs: ''remove-references-to ${lib.concatMapStrings (ref: " -t ${ref}") refs}'';
  in {
    mkDubDerivation = lib.makeOverridable ({
      src,
      nativeBuildInputs ? [],
      dubJSON ? src + "/dub.json",
      passthru ? {},
      package ? lib.importJSON dubJSON,
      ...
    } @ attrs: stdenv.mkDerivation (attrs // {
      pname = package.name;
      nativeBuildInputs = [ dcompiler dub pkgs.removeReferencesTo ] ++ nativeBuildInputs;
      disallowedReferences = disallowedReferences deps;
      passthru = passthru // {
        inherit dub dcompiler pkgs;
      };
      src = lib.cleanSourceWith {
        filter = filterDub;
        src = lib.cleanSource src;
      };
      preFixup = ''
        find $out/share/cgi-bin -type f -exec ${removeExpr (disallowedReferences deps)} '{}' + || true
      '';
      buildPhase = ''
        runHook preBuild
        export HOME=$PWD
        for dc_ in dmd ldmd2 gdmd; do
          echo "- check for D compiler $dc_"
          dc=$(type -P $dc_ || echo "")
          if [ ! "$dc" == "" ]; then
            break
          fi
        done
        if [ "$dc" == "" ]; then
          exit "Error: could not find D compiler"
        fi
        echo "$dc_ used as D compiler to build $pname"
        dub build --compiler=$dc --build=release --combined --skip-registry=all
        runHook postBuild
      '';
      checkPhase = ''
        runHook preCheck
        export HOME=$PWD
        dub test --combined --skip-registry=all
        runHook postCheck
      '';
      installPhase = ''
        runHook preInstall
        mkdir -p $out/share/cgi-bin
        cp -r "${targetOf package}" $out/share/cgi-bin
        install -m755 -D $out/share/cgi-bin/spine_search spine_search
        runHook postInstall
      '';
      postInstall = ''
        echo "HERE ${targetOf package} $out/share/cgi-bin"
        echo `ls -la $out/share/cgi-bin/spine_search`
      '';
      meta = lib.optionalAttrs (package ? description) {
        description = package.description;
      } // attrs.meta or {};
    } // lib.optionalAttrs (!(attrs ? version)) {
      # Use name from dub.json, unless pname and version are specified
      name = package.name;
    }));
  }
);
mkDubDerivation rec {
  name = "spine-search-${version}";
  version = "<<spine_version_set>>";
  src = ./.;
  buildInputs = [
    pkgs.sqlite (
      with pkgs; [
        nixFlakes
        rund
        dub
        ldc
        sqlite
      ]
    )
  ];
  # # buildPhase = [ ];
  # installPhase = ''
  #   install -m755 -D spine_search $out/bin/spine-search
  #   echo "built $out/bin/spine-search"
  # '';
  meta = with pkgs.lib; {
    homepage    = https://sisudoc.org;
    description = "a sisu like document parser";
    license     = licenses.agpl3Plus;
    platforms   = platforms.linux;
    maintainers = [ RalphAmissah ];
  };
}
#+END_SRC

** variables
*** spine version SET VERSION :version:set:project:

#+NAME: spine_version_set
#+BEGIN_SRC sh
0.11.3
#+END_SRC

*** set names SET

#+NAME: spine_search_db
#+BEGIN_SRC sh
spine.search.db
#+END_SRC

#+NAME: spine_search_cgi
#+BEGIN_SRC sh
spine_search
#+END_SRC

*** nixpkgs_path SETUP
**** nixpkgs select path SELECT

#+NAME: nixpkgs_path
#+BEGIN_SRC nix
<<nixpkgs_path_local>>
#+END_SRC

**** nixpkgs path options

- <nixpkgs>

#+NAME: nixpkgs_path_default
#+BEGIN_SRC nix
<nixpkgs>
#+END_SRC

#+NAME: nix_path_directory
#+BEGIN_SRC nix
nixpkgs=<<nixpkgs_path_local>>
#+END_SRC

#+NAME: project_path_local_src
#+BEGIN_SRC nix
/grotto-ra/repo/git.repo/projects/project-spine/doc-reform
#+END_SRC

#+NAME: project_path_local_bin
#+BEGIN_SRC nix
<<project_path_local_src>>/result/bin
#+END_SRC

#+NAME: project_path_cgi_bin
#+BEGIN_SRC nix
/var/www/cgi/cgi-bin
#+END_SRC

#+NAME: project_path_local_doc
#+BEGIN_SRC nix
/grotto-ra/repo/git.repo/projects/project-spine/doc-reform-markup/spine-markup-samples
#+END_SRC

#+NAME: project_path_local_out
#+BEGIN_SRC nix
/srv/www/spine/$SpineVER
#+END_SRC

#+NAME: project_path_local_out_
#+BEGIN_SRC nix
/tmp/spine/$SpineVER/www
#+END_SRC

#+NAME: project_path_local_out_static
#+BEGIN_SRC nix
/srv/www/spine
#+END_SRC

#+NAME: project_path_local_out_static_
#+BEGIN_SRC nix
/var/www
#+END_SRC


#+NAME: project_path_sqlite
#+BEGIN_SRC nix
/var/www/sqlite
#+END_SRC

#+NAME: nixpkgs_url
#+BEGIN_SRC nix
github:nixos/nixpkgs
#+END_SRC

#+BEGIN_SRC nix
<<nixpkgs_path_local>>
#+END_SRC

- local path SET WARN

#+NAME: nixpkgs_path_local
#+BEGIN_SRC nix
/nixpkgs-ra/nixpkgs
#+END_SRC

**** project path options

- local path SET WARN

#+NAME: nix_path_channel
#+BEGIN_SRC nix
/nix/var/nix/profiles/per-user/root/channels/nixos
#+END_SRC

** texlive xetex xelatex shell.nix
*** shell.nix :shell:

#+BEGIN_SRC nix
#!/usr/bin/env -S nix-shell --pure
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
  buildInputs = with pkgs; [
    nixFlakes
    nix-prefetch-git
    validatePkgConfig
    jq
    git
    fontconfig
    source-sans-pro
    source-serif-pro
    source-code-pro
    #(texlive.combine {
    #  inherit (texlive) scheme-tetex xetex fontspec footmisc multirow titlesec listings anysize float graphics helvetic times courier;
    #})
    texlive.combined.scheme-full
    dejavu_fonts dejavu_fontsEnv
    liberation_ttf
    evince
    zathura
    apvlv
  ];
    #FONTCONFIG_FILE = makeFontsConf { fontDirectories = [
    #  liberation_ttf
    #];
  shellHook = ''
    if [[ -e ".envrc" ]]; then
      source .envrc
    fi
    #for texfile in *.tex; do xelatex -interaction=nonstopmode $texfile; done
    #for texfile in *.tex; do xelatex -interaction=batchmode $texfile; done
  '';
}
#+END_SRC

*** notes

#+BEGIN_SRC sh
nix-shell --run 'which xetex'
echo 'for texfile in *.tex; do echo "* --> " ~ $texfile && xelatex -interaction=batchmode $texfile; rm *.aux *.log *.toc *.out; done'

$SpineBIN/spine --latex --serial --output="$SpineOUT" $SpinePOD/* && for texfile in $SpineOUT/latex/*.tex; do xelatex -interaction=nonstopmode $texfile; done 2>&1 | tee _err.xelatex_.org; ls $SpineOUT/latex/*.{tex,pdf}

/run/current-system/sw/share/X11/fonts/

kpsewhich pdftexconfig.tex
/nix/store/2r4qa8rbll085nmpx56jg1rbmbir1zkp-texlive-combined-2021/share/texmf/tex/generic/tex-ini-files/pdftexconfig.tex
/nix/store/2r4qa8rbll085nmpx56jg1rbmbir1zkp-texlive-combined-2021/share/texmf/fonts/opentype/public/

find: texclive-fonts.conf
fc-cache && mkfontscale && mkfontdir

fc-match LiberationSans

cd /nix/var/nix/profiles/system/sw/share/X11/fonts
fc-query LiberationSans-Regular.ttf | grep '^\s\+family:' | cut -d'"' -f2
Liberation Sans
fc-query LiberationMono-Regular.ttf | grep '^\s\+family:' | cut -d'"' -f2
Liberation Mono

fc-query DejaVuSans.ttf | grep '^\s\+family:' | cut -d'"' -f2

$XDG_DATA_HOME/fonts
~/.local/share/fonts
#+END_SRC