{ writeShellApplication , coreutils , util-linux , lib , koboInput , koboLabel ? "KOBOeReader" , koboManifest ? {} , ... }: with builtins // lib; let manValues = attrValues koboManifest; createMergeTool = local: remote: name: mergeTool: { inherit name; value = mergeTool "${local}/${name}" "${remote}/${name}"; }; collectMergeTools = local: remote: xs: listToAttrs (concatMap (v: map (name: createMergeTool local remote name v.mergeTool) v.targets) xs); onDevManifest = local: remote: collectMergeTools local remote (filter (v: v.remoteOnly) manValues; manifest = local: remote: collectMergeTools local remote (filter (v: ! v.remoteOnly) manValues); execApp = writeShellApplication { name = "kobo-exec"; runtimeInputs = [ coreutils ]; text = '' REMOTE_OR_LOCAL="''${1-}" KOBO_DIR="''${2-}" FILE="''${3-}" if [[ "$REMOTE_OR_LOCAL" == "REMOTE" ]]; then ${toShellVar "MANIFEST" (onDevManifest ${koboInput} "$KOBO_DIR")} FILEBASE="''${FILE/#$KOBO_DIR}" else ${toShellVar "MANIFEST" (manifest ${koboInput} "$KOBO_DIR")} FILEBASE="''${FILE/#${koboInput}}" fi ACTION="''${MANIFEST["$FILEBASE"]}" if [[ -n "$ACTION" ]]; then eval "$ACTION" elif [[ "$REMOTE_OR_LOCAL" == "LOCAL" ]]; then if [[ -d "$FILE" ]]; then mkdir -p "$KOBO_DIR/$FILEBASE" else cp -v "$FILE" "$KOBO_DIR/$FILEBASE" fi fi ''; }; in writeShellApplication { name = "KoboInstaller"; runtimeInputs = [ coreutils util-linux ]; text = '' KOBO_MOUNTPOINT="$(findmnt -nlo TARGET LABEL="${koboLabel}")" if [[ -z "$KOBO_MOUNTPOINT" ]]; then echo "Couldn't find a Kobo eReader volume with label ${koboLabel}. 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 "$KOBO_DIR/" -not -path "$KOBO_DIR/" -exec ${execApp}/bin/kobo-exec "REMOTE" "$KOBO_DIR" {} \; find "${koboInput}/" -not -path "${koboInput}/" -exec ${execApp}/bin/kobo-exec "LOCAL" "$KOBO_DIR" {} \; ''; }