2

I want to use Twitch package to copy any javascript files in the "central" directory to the "back" and "front" directories. This is the code:

{-# LANGUAGE OverloadedStrings #-}


module Main where

import Data.List
  ( isPrefixOf
  , tails
  , findIndex
  )
import System.Directory 
  ( createDirectoryIfMissing
  , removeDirectoryRecursive
  , copyFile
  )
import System.Directory.Recursive 
  ( getSubdirsRecursive
  , getFilesRecursive
  )
import Twitch
  ( defaultMain
  , (|>)
  )


main :: IO ()
main = do

  putStrLn "Haskell works <(^u^)>"

  -- Copy central folder to back and front, and setup recopy when central changes
  copyCentral
  defaultMain $ do 
    "./central/**/*.js" |> copyFileToBackAndFront




copyCentral :: IO ()
copyCentral = do

  createDirectoryIfMissing False "./back/src/central/" 
  removeDirectoryRecursive "./back/src/central"
  createDirectoryIfMissing False "./front/src/central/" 
  removeDirectoryRecursive "./front/src/central"

  centralFiles <- getFilesRecursive "./central/"
  centralDirs  <- getSubdirsRecursive "./central/"

  mapM_ (\d -> createDirectoryIfMissing True $ "./back/src" ++ tail d) centralDirs
  mapM_ (\d -> createDirectoryIfMissing True $ "./front/src" ++ tail d) centralDirs
  mapM_ (\f -> copyFile f $ "./back/src" ++ tail f) centralFiles
  mapM_ (\f -> copyFile f $ "./front/src" ++ tail f) centralFiles


copyFileToBackAndFront :: FilePath -> IO ()
copyFileToBackAndFront absolutePath = 
    maybe 
      (putStrLn "Error in the file path")
      getRelativePathAndCopy
      (findIndex (isPrefixOf "central") (tails absolutePath))
  where
    getRelativePathAndCopy n = do
      let relativePath = drop n absolutePath
      copyFile relativePath $ "./back/src/"  ++ relativePath
      copyFile relativePath $ "./front/src/" ++ relativePath
      putStrLn $ "Copied file " ++ relativePath ++ " to back and front"

And surprisingly it works! But i get the putStrLn output 2 times:

Copied file central\models\Board\Board.js to back and front
Copied file central\models\Board\Board.js to back and front

And I suspect it may be because of the program running in 2 threads, because sometimes I get interlaced output:

CCooppiieedd  ffiillee  cceennttrraall\\mmooddeellss\\BBooaarrdd\\BBooaarrdd..jjss  ttoo  bbaacckk  aanndd  ffrroonntt

CopiCeodp ifeidl ef icleen tcreanlt\rmaold\emlosd\eBlosa\rBdo\aBroda\rBdo.ajrsd .tjos  btaoc kb aacnkd  afnrdo nftr
ont

Also this happends when i run cabal v2-repl, i just tried cabal v2-run myprogram & and it does not work at all :(

Any help with both issues please?

RamiroPastor
  • 1,085
  • 1
  • 7
  • 18
  • 1
    Well, the documentation for `(|>)` says it adds the given action as callbacks for both the add and modify events (whatever those are). Perhaps on startup both events fire for each file that already exists? Or perhaps writing a file causes a creation event and an immediately following modification event? – Daniel Wagner Feb 21 '21 at 19:26
  • Well, if i use `(|+)` it still runs 2 times – RamiroPastor Feb 21 '21 at 19:34

0 Answers0