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

- [[./config_env.org][config_env.org]]

* nix :nix:
** flake.nix :flake:

#+HEADER: :tangle ../flake.nix
#+HEADER: :noweb yes
#+BEGIN_SRC nix
{
  description = "spine (sisu like parser & document generator) made available to process markup samples";
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";
  inputs.spine = {
    url = "<<sisudoc_spine_nix_src>>";
    inputs.nixpkgs.follows = "nixpkgs";
    flake = true;
  };
  inputs.d-overlay = {
    url = "<<sisudoc_dlang_nix_overlay_src>>";
    inputs.nixpkgs.follows = "nixpkgs";
    flake = true;
  };
  outputs = {
    self,
    nixpkgs,
    flake-utils,
    spine,
    d-overlay,
    ...
  }@inputs: let
    version = "<<spine_version>>";
    shell = ./shell.nix;
    devEnv = ./nixDevEnv.sh;
    supportedSystems = ["x86_64-linux"]; # [ "x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin" ];
    forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
    nixpkgsFor = forAllSystems (system: import nixpkgs {inherit system;}); # nixpkgs instantiated for supported system types
  in {
    packages = forAllSystems (system: let
      pkgs = nixpkgsFor.${system};
    in {
      default = spine.packages.${system}.default;
      #spine-nixpkgs-dmd = spine.packages.${system}.spine-nixpkgs-dmd;
      spine-overlay-dmd = spine.packages.${system}.spine-overlay-dmd;
      #spine-nixpkgs-ldc = spine.packages.${system}.spine-nixpkgs-ldc;
      spine-overlay-ldc = spine.packages.${system}.spine-overlay-ldc;
      #vendorSha256 = "sha256-0Q00000000000000000000000000000000000000000=";
    });
    apps = forAllSystems (system: {
      default = {
        type = "app";
        program = "${self.packages.${system}.default}/bin/spine";
      };
    });
    devShells = forAllSystems (system: let
      pkgs = nixpkgsFor.${system};
      shellHook = ''
        export Date=`date "+%Y%m%d"`
        ## set local values in .envrc-local (or here if you must)
        echo "  ❯❯ ./result/bin/spine -v --source --pod --epub --html --html-link-pdf --html-link-curate --html-link-markup --curate --output=./OUTPUT_TEST_sisudocSpine ./markup/pod/*";
      '';
    in
      with pkgs; {
        dsh = mkShell {
          name = "spine base dev shell";
          inherit shell;
          inherit devEnv;
          packages = [
            ldc
            #dmd
            dub
            gnumake
            sqlite
          ];
          inherit shellHook;
        };
        dsh-spine = spine.devShells.${system}.default;
        dsh-overlay-dmd = d-overlay.devShells.${system}.dsh-overlay-dmd-dub;
        dsh-nixpkgs-dmd = d-overlay.devShells.${system}.dsh-nixpkgs-dmd-dub;
        dsh-overlay-ldc = d-overlay.devShells.${system}.dsh-overlay-ldc-dub;
        dsh-nixpkgs-ldc = d-overlay.devShells.${system}.dsh-nixpkgs-ldc-dub;
        dsh-epub = mkShell {
          name = "spine dev shell for epub output";
          inherit shell;
          inherit devEnv;
          packages = [
            ldc
            #dmd
            dub
            gnumake
            sqlite
            libxml2
            html-tidy
            xmlstarlet
            epubcheck
            ebook_tools
            libxml2
            html-tidy
            xmlstarlet
            epubcheck
            ebook_tools
            epr
            sigil
            calibre #(suite includes: ebook-viewer)
            koreader
            foliate
          ];
          inherit shellHook;
        };
        dsh-html = mkShell {
          name = "spine dev shell for latex & pdf output";
          inherit shell;
          inherit devEnv;
          packages = [
            ldc
            #dmd
            dub
            gnumake
            sqlite
            # ❯❯ text-mode web browsers
            elinks
            links2
            lynx
            w3m
            # ❯❯ light graphical
            #dillo
          ];
          inherit shellHook;
        };
        dsh-latex-pdf = mkShell {
          name = "spine dev shell for latex & pdf output";
          inherit shell;
          inherit devEnv;
          packages = [
            ldc
            #dmd
            dub
            gnumake
            source-sans-pro
            source-serif-pro
            source-code-pro
            texlive.combined.scheme-full
          ];
          inherit shellHook;
        };
        dsh-sqlite = mkShell {
          name = "spine dev shell for latex & pdf output";
          inherit shell;
          inherit devEnv;
          packages = [
            ldc
            #dmd
            dub
            gnumake
            sqlite
          ];
          inherit shellHook;
        };
        dsh-i18n = mkShell {
          name = "spine dev shell internationalization, po4a";
          inherit shell;
          inherit devEnv;
          packages = [
            ldc
            #dmd
            dub
            gnumake
            sqlite
            perl538Packages.Po4a
          ];
          inherit shellHook;
        };
        default = import ./shell.nix {inherit pkgs;};
      });
  };
}
#+END_SRC

** shell.nix :shell:

#+HEADER: :tangle ../shell.nix
#+HEADER: :tangle-mode (identity #o755)
#+HEADER: :shebang "#!/usr/bin/env -S nix-shell --pure\n#!nix-shell -i bash"
#+HEADER: :noweb yes
#+BEGIN_SRC nix
{pkgs ? import <nixpkgs> {}}:
with pkgs;
  mkShell {
    buildInputs = [
      # ❯❯❯ nix_related
      ##nix
      #direnv
      #nixVersions.latest #nixVersions.latest #nixVersions.git
      #nix-prefetch-git
      #validatePkgConfig
      nix-output-monitor
      #nix-tree
      #jq
      #alejandra
      #git
      # ❯❯❯ dev
      #gnumake
      #ps
      # ❯❯❯ d_build_related
      # ❯❯ package manager
      #dub
      # ❯❯ compiler
      #ldc
      ##rund
      # ❯❯ linker
      ##lld
      ##mold
      # ❯❯ builder
      ##ninja
      ##meson
      # ❯❯❯ sqlite search related
      #sqlite
      # ❯❯❯ pdf_latex_related
      # source-sans-pro
      # source-serif-pro
      # source-code-pro
      # texlive.combined.scheme-full
      # ❯❯❯ xml_and_epub_related
      # libxml2
      # html-tidy
      # xmlstarlet
      # epubcheck
      # ebook_tools
      # epr
      # sigil
      # calibre #(suite includes: ebook-viewer)
      # koreader
      # foliate
      # ❯❯❯ i18n translation related
      # perl538Packages.Po4a
    ];
    shellHook = ''
    '';
  }
#+END_SRC

** default.nix :default:

#+HEADER: :tangle ../default.nix
#+HEADER: :tangle-mode (identity #o755)
#+HEADER: :shebang "#!/usr/bin/env -S nix-build"
#+BEGIN_SRC nix
{pkgs ? import <nixpkgs> {}}:
pkgs.callPackage ./devenv.nix {}
#+END_SRC

* devEnv

nix profile install .

#+HEADER: :tangle ../devenv.nix
#+HEADER: :tangle-mode (identity #o644)
#+BEGIN_SRC nix
{
  pkgs ? import <nixpkgs> {},
  name ? "user-env",
}:
with pkgs;
  buildEnv {
    inherit name;
    extraOutputsToInstall = ["out" "man" "lib"]; # to get all needed symlinks
    paths = [
      # ❯❯❯ nix_related
      #nix # if not on NixOS, this is needed
      direnv
      nixVersions.latest #nixVersions.latest #nixVersions.git
      nix-prefetch-git
      validatePkgConfig
      nix-output-monitor
      nix-tree
      jq
      #alejandra
      git
      # ❯❯❯ dev
      gnumake
      ps
      # ❯❯❯ d_build_related
      # ❯❯ package manager
      dub
      # ❯❯ compiler
      #dmd
      ldc
      # ❯❯❯ sqlite search related
      sqlite
      # this will create a script that will rebuild and upgrade your setup; using shell script syntax
      (writeScriptBin "nix-rebuild" ''
        #!${stdenv.shell}
        #cd <path-to-flake> || exit 1
        nix flake update
        nix profile upgrade '.*'
      '')
      # puts in your root the nixpkgs version
      (writeTextFile {
        name = "nixpkgs-version";
        destination = "/nixpkgs-version";
        text = lib.version;
      })
    ];
  }
#+END_SRC

** derivation.nix :default:

#+HEADER: :tangle ../derivation.nix
#+HEADER: :tangle-mode (identity #o644)
#+HEADER: :noweb yes
#+BEGIN_SRC nix
{
  pkgs ? import <nixpkgs> {},
  stdenv ? pkgs.stdenv,
  lib ? pkgs.lib,
  ldc ? null,
  dcompiler ? pkgs.ldc,
  dub ? pkgs.dub,
}:
assert dcompiler != null;
with (
  with lib; let
    filterDub = name: type: let
      baseName = baseNameOf (toString name);
    in
      ! ( # filter function to remove the .dub package folder from src
        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
              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 run --compiler=$DC --build=release --combined --skip-registry=all
              runHook postBuild
            '';
            checkPhase = ''
              runHook preCheck
              HOME="$PWD"
              dub test --combined --skip-registry=all
              runHook postCheck
            '';
            installPhase = ''
              runHook preInstall
              mkdir -p $out/bin
              cp -r "${targetOf package}" $out/bin
              #cp -rv "${targetOf package}" $out/sisudoc-spine-markup-samples/.
              #cp -rv ./markup $out/sisudoc-spine-markup-samples/.
              runHook postInstall
            '';
            #postInstall= ''
            #  cp -rv ./markup $out/sisudoc-spine-markup-samples/.
            #'';
            meta =
              lib.optionalAttrs (package ? description) {
                description = package.description;
              }
              // attrs.meta or {};
          }
          // lib.optionalAttrs (!(attrs ? version)) {
            name = package.name; # use name from dub.json, unless pname and version are specified
          }));
  }
);
  mkDubDerivation rec {
    pname = "spine";
    version = "<<spine_version>>";
    #zipfile = "spine-0.12.0-tag-0.11.2.r107.gf89a107.tar.gz";
    src = fetchTarball {
      url = "<<spine_tarball_path_url>>";
      sha256 = "<<spine_tarball_sha256>>";
    };
    nativeBuildInputs = with pkgs; [dub ldc];
    buildInputs = with pkgs; [nixVersions.latest sqlite];
    meta = with pkgs.lib; {
      description = "A sisu like parser & document generator";
      longDescription = ''
        a sisu like parser & document generator
      '';
      homepage = "https://sisudoc.org";
      license = licenses.agpl3Plus;
      platforms = platforms.linux;
      maintainers = ["RalphAmissah"];
    };
  }
#+END_SRC

#src = ./.;

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

#+NAME: spine_tarball_path
#+HEADER: :noweb yes
#+BEGIN_SRC nix
/home/ralph/grotto/repo/git.repo/projects/doc-reform/code/software/tarball
#+END_SRC

#+NAME: spine_tarball_path_url
#+HEADER: :noweb yes
#+BEGIN_SRC nix
file://<<spine_tarball_path>>/<<spine_tarball_filename>>
#+END_SRC

#+NAME: spine_git_file_path
#+HEADER: :noweb yes
#+BEGIN_SRC nix
/home/ralph/grotto/repo/git.repo/projects/doc-reform/code/software/sisudoc-spine
#+END_SRC

#+NAME: nixpkgs_local
#+BEGIN_SRC sh
/srv/nixpkgs-dev/nixpkgs
#+END_SRC

#+NAME: spine_git_file_path_url
#+HEADER: :noweb yes
#+BEGIN_SRC nix
git+file://<<spine_git_file_path>>
#+END_SRC

#+NAME: spine_tarball_filename
#+HEADER: :noweb yes
#+BEGIN_SRC nix
spine-0.12.0-tag-0.11.2.r107.gf89a107.tar.gz
#+END_SRC

#+NAME: spine_tarball_sha256
#+HEADER: :noweb yes
#+BEGIN_SRC nix
sha256:03dr7dn7kq6arw4ry7qar13iqmi1caw70imfjwi8qr7g2j4mnk2q
#+END_SRC

#+BEGIN_SRC nix
sha256:0000000000000000000000000000000000000000000000000000
#+END_SRC

/home/ralph/grotto/repo/git.repo/projects/project-spine/tarball

#+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
github:NixOS/nixpkgs/nixpkgs-unstable
#+END_SRC

#+BEGIN_SRC nix
"nixpkgs/nixos-unstable";
#+END_SRC

#+BEGIN_SRC nix
"nixpkgs/nixos-23.05";
#+END_SRC

#+HEADER: :noweb yes
#+BEGIN_SRC nix
<<nixpkgs_path_local>>
#+END_SRC

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

#+NAME: spine_version
#+HEADER: :noweb yes
#+BEGIN_SRC emacs-lisp
<<./sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org:spine_project_version()>>
#+END_SRC

*** spine project git sources VERSION :version:set:project:

#+NAME: sisudoc_spine_nix_src
#+HEADER: :noweb yes
#+BEGIN_SRC emacs-lisp
<<./sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org:sisudoc_spine_nix_src()>>
#+END_SRC

#+NAME: sisudoc_dlang_nix_overlay_src
#+HEADER: :noweb yes
#+BEGIN_SRC emacs-lisp
<<./sisudoc_spine_version_info_and_doc_header_including_copyright_and_license.org:sisudoc_dlang_nix_overlay_src()>>
#+END_SRC