From d3fb236c7f1e731f77fc3f384a7d195215091c4f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Hamal=20Dvo=C5=99=C3=A1k?= <mordae@anilinux.org>
Date: Sun, 4 Oct 2020 14:31:23 +0200
Subject: [PATCH] Add developWith for app reloading with ghcid
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Jan Hamal Dvořák <mordae@anilinux.org>
---
 hikaru.cabal          |  5 ++++-
 lib/Hikaru.hs         |  2 ++
 lib/Hikaru/Develop.hs | 47 +++++++++++++++++++++++++++++++++++++++++++
 package.yaml          |  1 +
 4 files changed, 54 insertions(+), 1 deletion(-)
 create mode 100644 lib/Hikaru/Develop.hs

diff --git a/hikaru.cabal b/hikaru.cabal
index 3d892b4..03f3b70 100644
--- a/hikaru.cabal
+++ b/hikaru.cabal
@@ -4,7 +4,7 @@ cabal-version: 1.12
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 8bbf377869281f273f43485c46ccce646be610521dbf18fa016b0762e07d767f
+-- hash: f2e507d7c6d6469807c9edd22fe9f5628b08203e542661f8e917468fd1f856e8
 
 name:           hikaru
 version:        0.1.0.0
@@ -45,6 +45,7 @@ library
       Hikaru.Route
       Hikaru.Types
   other-modules:
+      Hikaru.Develop
       Paths_hikaru
   hs-source-dirs:
       lib
@@ -59,6 +60,7 @@ library
     , containers >=0.6 && <0.7
     , cookie >=0.4 && <0.5
     , cryptonite >=0.26 && <0.27
+    , foreign-store >=0.2 && <0.3
     , http-types >=0.12 && <0.13
     , lucid >=2.9 && <2.10
     , memory >=0.15 && <0.16
@@ -98,6 +100,7 @@ test-suite spec
     , containers >=0.6 && <0.7
     , cookie >=0.4 && <0.5
     , cryptonite >=0.26 && <0.27
+    , foreign-store >=0.2 && <0.3
     , hikaru
     , hspec
     , http-types >=0.12 && <0.13
diff --git a/lib/Hikaru.hs b/lib/Hikaru.hs
index 6e38b2e..6d33eaf 100644
--- a/lib/Hikaru.hs
+++ b/lib/Hikaru.hs
@@ -16,6 +16,7 @@ module Hikaru
     module Hikaru.Action
   , module Hikaru.Config
   , module Hikaru.CSRF
+  , module Hikaru.Develop
   , module Hikaru.Dispatch
   , module Hikaru.Form
   , module Hikaru.Link
@@ -28,6 +29,7 @@ where
   import Hikaru.Action
   import Hikaru.Config
   import Hikaru.CSRF
+  import Hikaru.Develop
   import Hikaru.Dispatch
   import Hikaru.Form
   import Hikaru.Link
diff --git a/lib/Hikaru/Develop.hs b/lib/Hikaru/Develop.hs
new file mode 100644
index 0000000..5bd2a69
--- /dev/null
+++ b/lib/Hikaru/Develop.hs
@@ -0,0 +1,47 @@
+{-|
+Module      :  Hikaru.Develop
+Copyright   :  Jan Hamal Dvořák
+License     :  AGPL-3
+
+Maintainer  :  mordae@anilinux.org
+Stability   :  unstable
+Portability :  non-portable (ghc)
+
+This module provides development and testing utilities.
+-}
+
+module Hikaru.Develop
+  ( developWith
+  )
+where
+  import Relude
+
+  import Control.Concurrent (killThread, forkFinally)
+  import Foreign.Store
+
+
+  -- |
+  -- To be used with @ghcid@ to reload the app when the source changes.
+  --
+  developWith :: IO () -> IO ()
+  developWith main = do
+    store <- mapM readStore =<< lookupStore 1
+    stash <- case store of
+               Nothing -> do
+                 stash <- newEmptyMVar
+                 writeStore (Store 1) stash
+                 return stash
+
+               Just stash -> do
+                 return stash
+
+    tryTakeMVar stash >>= \case
+      Nothing          -> return ()
+      Just (lock, tid) -> killThread tid >> takeMVar lock
+
+    lock' <- newEmptyMVar
+    tid'  <- forkFinally main $ const $ putMVar lock' ()
+    putMVar stash (lock', tid')
+
+
+-- vim:set ft=haskell sw=2 ts=2 et:
diff --git a/package.yaml b/package.yaml
index c8d9d78..9d3a337 100644
--- a/package.yaml
+++ b/package.yaml
@@ -52,6 +52,7 @@ dependencies:
   - containers         >= 0.6  && <0.7
   - cookie             >= 0.4  && <0.5
   - cryptonite         >= 0.26 && <0.27
+  - foreign-store      >= 0.2  && <0.3
   - http-types         >= 0.12 && <0.13
   - lucid              >= 2.9  && <2.10
   - memory             >= 0.15 && <0.16
-- 
GitLab