From d6adbc7c45a3894d9e985f79e5c43a908bbb80e0 Mon Sep 17 00:00:00 2001
From: Daniel Firth <dan.firth@homotopic.tech>
Date: Thu, 29 Dec 2022 10:19:48 +0000
Subject: [PATCH] apps.procex: init with simple commands

---
 flake.nix         |  6 +++++
 shell/ShellRC.hs  | 52 ++++++++++++++++++++++++++++++++++++++
 shell/default.nix | 64 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 122 insertions(+)
 create mode 100644 shell/ShellRC.hs
 create mode 100644 shell/default.nix

diff --git a/flake.nix b/flake.nix
index 23e19ff0..29d066ca 100644
--- a/flake.nix
+++ b/flake.nix
@@ -78,6 +78,7 @@
           program = "${run-impure-tests}/bin/run-impure-tests";
         };
 
+        procex = import ./shell/default.nix { haskellPackages = horizon-platform-prev.legacyPackages.${system}; inherit (pkgs) runCommand writeShellScriptBin; };
       in
       {
 
@@ -90,6 +91,11 @@
             program = "${horizon-gen-gitlab-ci}/bin/gen-gitlab-ci";
           };
 
+          procex = {
+            type = "app";
+            program = "${procex}/bin/procex-shell";
+          };
+
           run-impure-tests = run-impure-tests-app;
         };
 
diff --git a/shell/ShellRC.hs b/shell/ShellRC.hs
new file mode 100644
index 00000000..1af79fa9
--- /dev/null
+++ b/shell/ShellRC.hs
@@ -0,0 +1,52 @@
+{-# LANGUAGE NoMonomorphismRestriction #-}
+{-# OPTIONS_GHC -Wno-missing-signatures #-}
+{-# OPTIONS_GHC -Wno-unused-imports #-}
+
+module ShellRC where
+
+import qualified Control.Lens              as L
+import qualified Data.Aeson                as A
+import qualified Data.Aeson.Key            as A
+import qualified Data.Aeson.KeyMap         as A
+import qualified Data.Aeson.Lens           as L
+import qualified Data.ByteString.Lazy      as B
+import           Data.ByteString.Lazy.UTF8 as BLU
+import qualified Data.ByteString.Lazy.UTF8 as BU
+import qualified Data.Map                  as Map
+import           Data.Text                 (Text)
+import qualified Data.Text                 as T
+import qualified Data.Text.Encoding        as T
+import qualified Data.Yaml                 as Y
+import qualified Data.Yaml.Pretty          as Y
+import           Network.HTTP.Simple
+import           Path
+import           Procex.Prelude
+import           Procex.Shell              hiding (promptFunction)
+import           System.Directory
+import           System.Environment
+
+promptFunction :: [String] -> Int -> IO String
+promptFunction _modules _line = do
+  d <- getEnv "PWD"
+  setCurrentDirectory d
+  pure $ d <> ": "
+
+_init :: IO ()
+_init = do
+  initInteractive
+  getEnv "REALHOME" >>= setEnv "HOME" -- Set by the script that launches GHCi
+
+hackagePkg :: Text -> IO A.Value
+hackagePkg x = do
+  k <- parseRequest $ "http://hackage.haskell.org/package/" <> T.unpack x
+  getResponseBody <$> httpJSON k
+
+hackagePkgLatest :: Text -> IO Text
+hackagePkgLatest x = Prelude.last . Map.keys . A.toMapText . L.view L._Object <$> hackagePkg x
+
+runAllFeedback :: IO ()
+runAllFeedback = do
+  (x :: Either Y.ParseException A.Value) <- Y.decodeFileEither "feedback.yaml"
+  t <- getEnv "TERM"
+  let y = Map.keys . A.toMapText . L.view (L._Right . L._Object . L.ix "loops" . L._Object) $ x
+  mapM_ (captureLazyNoThrow . mq t "--command" "nix" "run" "github:NorfairKing/feedback" "--" . T.unpack) y
diff --git a/shell/default.nix b/shell/default.nix
new file mode 100644
index 00000000..56ae06ea
--- /dev/null
+++ b/shell/default.nix
@@ -0,0 +1,64 @@
+{ haskellPackages, writeShellScriptBin, runCommand }:
+
+let
+
+  shellrcSrcPath = ./.;
+  shellrcModule = "ShellRC";
+
+  shellrcSrc = shellrcSrcPath;
+  shellrcModulePath = builtins.replaceStrings [ "." ] [ "/" ] shellrcModule + ".hs";
+
+  ghc = haskellPackages.ghcWithPackages (p: with p; [
+    bytestring
+    containers
+    dhall
+    http-conduit
+    lens
+    lens-aeson
+    path
+    procex
+    text
+    yaml
+  ]);
+
+  args = builtins.concatStringsSep " " [
+    "-XDataKinds"
+    "-XExtendedDefaultRules"
+    "-XGHC2021"
+    "-XOverloadedStrings"
+    "-XOverloadedLabels"
+    "-Wall"
+    "-Wno-type-defaults"
+  ];
+
+  shellrc = runCommand "shellrc" { } ''
+    cp ${shellrcSrc} --no-preserve=all -rT $out
+    ${ghc}/bin/ghc -c -dynamic --make -i"$out" ${args} $out/${shellrcModulePath}
+  '';
+
+  init = runCommand "ghci-init" { } ''
+    cat > $out <<END
+      :set +m -interactive-print Text.Pretty.Simple.pPrint
+
+      :l ${shellrcModule}
+
+      import Procex.Shell.Labels
+
+      :set prompt-function promptFunction
+
+      _init
+    END
+    grep -E '^import .*$' < ${shellrcSrc}/${shellrcModulePath} >> $out
+  '';
+
+in
+
+(writeShellScriptBin "procex-shell" ''
+
+  home="$HOME/.local/share/ghci-shell"
+
+  mkdir -p "$home"
+
+  exec env GHCRTS="-c" HOME="$home" REALHOME="$HOME" ${ghc}/bin/ghci ${args} -ignore-dot-ghci -i -i${shellrc} -ghci-script ${init} "$@"
+
+'').overrideAttrs (old: old // { passthru = { shellPath = "/bin/procex-shell"; }; })
-- 
GitLab