Dealing with life in Haskell
- Magnus Therning
I bet you have at least one silly little thing at work that, whenever it happens, you let out a sigh, maybe roll your eyes and whish that everyone would use a proper operating system. A few days I finally decided to do something about one of my things like that. At work, Windows users will at times for some strange reason, manually create directories inside their work area, even though the directories actually are under version control. Invariably they get the case wrong and due to an onfortunate combination of case insensitive filesystem on the client (Windows) and a version control system the cares about case (Perforce). This results in files ending up all over the place even though they belong in the same directory. The Windows users are none the wiser, they simply don’t see the problem. Since I use a sane system (Linux) I do notice, and when I see it I sigh and roll my eyes.
Here’s my take on solving the problem:
module Main where
import Control.Monad
import Data.Char
import System.Directory
import System.Environment
import System.FilePath
import System.IO.HVFS.Utils
import System.Posix.Files
data IFile = IFile
{ iFileIPath :: FilePath
, iFileIName :: FilePath
, iFileFull :: FilePath
} deriving (Show)
toIFile :: FilePath -> IFile
toIFile fp = IFile path file fp
where
path = map toLower $ takeDirectory fp
file = map toLower $ takeFileName fp
listFilesR :: FilePath -> IO [IFile]
listFilesR path =
recurseDir SystemFS path >>=
filterM doesFileExist >>=
mapM (return . toIFile)
linkFile :: FilePath -> IFile -> IO ()
linkFile dest ifile = do
createDirectoryIfMissing True newDir
createLink (iFileFull ifile) newFile
where
newDir = normalise $ dest </> (iFileIPath ifile)
newFile = newDir </> (iFileIName ifile)
main :: IO ()
main = do
args <- getArgs
listFilesR (args !! 0) >>= mapM_ (linkFile $ args !! 1)
Yes, this is the code I wrote in Literate Haskell, but I think I’d better not disclose my rant against clueless Windows users publically ;-)