@@ -10,31 +10,42 @@ import System.Directory (
1010 XdgDirectory (.. ),
1111 createDirectoryIfMissing ,
1212 doesFileExist ,
13+ getCurrentDirectory ,
1314 getModificationTime ,
1415 getXdgDirectory ,
1516 )
1617import System.Exit (ExitCode (.. ))
1718import System.FilePath ((</>) )
1819import System.Process
20+
1921#ifndef mingw32_HOST_OS
20- import System.Posix.Signals (Handler (.. ), installHandler , sigINT )
22+ import System.Posix.Signals (Handler (.. ), installHandler , sigINT )
2123#endif
2224
2325main :: IO ()
2426main = do
2527 cacheDir <- getXdgDirectory XdgCache " dataframe_repl"
28+ currDir <- getCurrentDirectory
29+ print currDir
2630 createDirectoryIfMissing True cacheDir
2731
28- let filepath = cacheDir </> " dataframe.ghci"
29- shouldDownload <- needsUpdate filepath
32+ let ghciScript = cacheDir </> " dataframe.ghci"
33+ projectFile = cacheDir </> " cabal.project"
34+ cabalFile = cacheDir </> " df-repl.cabal"
35+ mainFile = cacheDir </> " Main.hs"
36+
37+ -- Ensure the directory is a valid Cabal project with a local target to repl into.
38+ ensureBoilerplate projectFile cabalFile mainFile
3039
40+ -- Keep your ghci script updated (weekly).
41+ shouldDownload <- needsUpdate ghciScript
3142 when shouldDownload $ do
3243 putStrLn " \ESC [92mDownloading latest version of dataframe config...\ESC [0m"
3344 output <-
3445 readProcess
3546 " curl"
3647 [ " --output"
37- , filepath
48+ , ghciScript
3849 , " https://raw.githubusercontent.com/mchav/dataframe/refs/heads/main/dataframe.ghci"
3950 ]
4051 " "
@@ -45,34 +56,75 @@ main = do
4556 let command = " cabal"
4657 args =
4758 [ " repl"
48- , " --ignore-project"
59+ , " exe:df-repl"
60+ , " --project-file=" ++ projectFile
4961 , " -O2"
50- , " --build-depends"
51- , " dataframe"
52- , " --repl-option=-ghci-script=" ++ filepath
62+ , " --repl-option=-ghci-script=" ++ ghciScript
5363 ]
54- let baseCp =
64+
65+ baseCp =
5566 (proc command args)
56- { cwd = Just cacheDir
67+ { cwd = Just currDir
5768 , std_in = Inherit
5869 , std_out = Inherit
5970 , std_err = Inherit
6071 }
72+
6173#ifdef mingw32_HOST_OS
62- cp = baseCp {delegate_ctlc = True }
74+ cp = baseCp { delegate_ctlc = True }
6375#else
6476 cp = baseCp
6577#endif
78+
6679#ifndef mingw32_HOST_OS
6780 -- Unix: ignore Ctrl-C in the wrapper so the child handles it.
68- bracket (installHandler sigINT Ignore Nothing )
69- (\ old -> installHandler sigINT old Nothing )
70- (\ _ -> runChild cp)
81+ bracket
82+ (installHandler sigINT Ignore Nothing )
83+ (\ old -> installHandler sigINT old Nothing )
84+ (\ _ -> runChild cp)
7185#else
7286 -- Windows: delegate Ctrl-C handling to the child.
7387 runChild cp
7488#endif
7589
90+ ensureBoilerplate :: FilePath -> FilePath -> FilePath -> IO ()
91+ ensureBoilerplate projectFile cabalFile mainFile = do
92+ -- cabal.project
93+ writeIfMissing
94+ projectFile
95+ $ unlines
96+ [ " packages: ."
97+ ]
98+
99+ writeIfMissing
100+ cabalFile
101+ $ unlines
102+ [ " cabal-version: 3.0"
103+ , " name: df-repl"
104+ , " version: 0.1.0.0"
105+ , " build-type: Simple"
106+ , " "
107+ , " executable df-repl"
108+ , " main-is: Main.hs"
109+ , " hs-source-dirs: ."
110+ , " default-language: Haskell2010"
111+ , " build-depends: base, dataframe, text, time, random"
112+ ]
113+
114+ writeIfMissing
115+ mainFile
116+ $ unlines
117+ [ " module Main where"
118+ , " "
119+ , " main :: IO ()"
120+ , " main = putStrLn \" df-repl\" "
121+ ]
122+
123+ writeIfMissing :: FilePath -> String -> IO ()
124+ writeIfMissing fp contents = do
125+ exists <- doesFileExist fp
126+ unless exists $ writeFile fp contents
127+
76128runChild :: CreateProcess -> IO ()
77129runChild cp = do
78130 (_, _, _, ph) <- createProcess cp
0 commit comments