{ config, pkgs, lib, ... }: with builtins // lib; let cfg = config.build; copyFileFunc = '' function copyFile() { local SOURCE="$1" local RELTARGET="$2" local EXECUTABLE="3" local TARGET TARGET="$(realpath -m "$REALOUT/$RELTARGET")" if [[ ! $TARGET == $REALOUT* ]]; then echo "Error installing file $RELTARGET outside of kobo src" >&2 exit 1 fi mkdir -pv "$(dirname "$TARGET")" if [[ -d "$SOURCE" ]]; then if [[ -d "$TARGET" ]]; then cp -rfv "$SOURCE/." "$TARGET/" else cp -rfv "$SOURCE" "$TARGET" fi else cp -fv "$SOURCE" "$TARGET" fi if [[ "$EXECUTABLE" == "inherit" ]]; then : elif [[ "$EXECUTABLE" ]]; then chmod +x "$TARGET" else chmod -x "$TARGET" fi } ''; copyFile = { source, executable, target, ... }: '' copyFile ${escapeShellArgs [ source (if executable == null then "inherit" else toString executable) ]} ''; installFile = writeShellApplication { name = "kobo-install-file"; runtimeInputs = [ pkgs.coreutils ]; text = '' DRY_RUN_ARG="''${1-}" LOCAL_DIR="''${2-}" KOBO_DIR="''${3-}" LOCAL_FILE="''${4-}" FILENAME="''${LOCAL_FILE/#$LOCAL_DIR}" KOBO_FILE="$KOBO_DIR/$FILENAME" ${toShellVar "MANIFEST" (cfg.manifestLookupFor "$LOCAL_FILE" "$KOBO_FILE")} ACTION="''${MANIFEST["$FILENAME"]}" if [[ -n "$ACTION" ]]; then $DRY_RUN_ARG eval "$ACTION" elif [[ -d "$LOCAL_FILE" ]]; then $DRY_RUN_ARG mkdir -p "$KOBO_FILE" else $DRY_RUN_ARG mkdir -p "$(dirname "$KOBO_FILE")" $DRY_RUN_ARG cp -f "$LOCAL_FILE" "$KOBO_FILE" fi ''; }; in { options.build = { allFiles = mkOption { readOnly = true; internal = true; default = with config; concatMap (_: attrValues) [ file kfmon.file kobo.file koreader.file nickel.file plato.file ]; apply = filter (v: v.enable); }; allManifests = mkOption { readOnly = true; internal = true; default = with config; concatMap (_: attrValues) [ manifest kfmon.manifest kobo.manifest koreader.manifest nickel.manifest plato.manifest ]; apply = filter (v: v.enable); }; manifestLookup = mkOption { readOnly = true; internal = true; type = with types; attrsOf (functionTo (functionTo str)); default = let split = concatMap ({ targets, mergeTool, ... }: map (name: { inherit name; value = mergeTool; }) targets); in listToAttrs split; }; manifestLookupFor = mkOption { readOnly = true; internal = true; type = with types; functionTo (functionTo (attrsOf str)); default = x: y: mapAttrs (_: f: f x y) cfg.manifestLookup; }; src = mkOption { type = types.package; readOnly = true; internal = true; default = pkgs.stdenv.mkDerivation { inherit (config) src; name = "kobo_src"; phases = [ "installPhase" ]; installPhase = '' mkdir -pv $out cp -rv $src/. $out/ chmod -R +w $out REALOUT="$(realpath -m "$out")" ${copyFileFunc} ${concatStringsSep "\n" ( mapAttrsToList (_: copyFile) cfg.allFiles )} ''; }; }; installer = mkOption { type = types.package; readOnly = true; internal = true; default = pkgs.writeShellApplication { name = "kobo-installer"; runtimeInputs = [ pkgs.coreutils pkgs.util-linux ]; text = '' #TODO DRY_RUN_ARG KOBO_LABEL="''${1:-KOBOeReader}" KOBO_MOUNTPOINT="$(findmnt -nlo TARGET LABEL="$KOBO_LABEL")" if [[ -z "$KOBO_MOUNTPOINT" ]]; then echo "Couldn't find a Kobo eReader volume with label $KOBO_LABEL. Are you sure one is actually mounted?" exit 255 fi KOBO_DIR="$KOBO_MOUNTPOINT/.kobo" if [[ ! -d "$KOBO_DIR" ]]; then echo "It doesn't seem like $KOBO_MOUNTPOINT actually points to a Kobo eReader since it doesn't contain a .kobo directory . . . " exit 255 fi find "${cfg.src}/" -not -path "${cfg.src}/" -exec ${installFile}/bin/kobo-install-file "" "${cfg.src}" "$KOBO_DIR" {} \; ''; }; }; }; }