moduleDevelopment.Shake.DerivedwhereimportControl.MonadimportControl.Monad.IO.ClassimportSystem.ProcessimportSystem.DirectoryimportSystem.ExitimportqualifiedData.ByteString.Char8asBSimportDevelopment.Shake.CoreimportDevelopment.Shake.FileimportDevelopment.Shake.FilePath-- | Execute a system command. This function will raise an error if the exit code is non-zero.-- Before running 'system'' make sure you 'need' any required files.system'::FilePath->[String]->Action()system'pathargs=doletpath2=toNativepathletcmd=unwords$path2:argsputLoudcmdres<-traced("system "++cmd)$rawSystempath2argswhen(res/=ExitSuccess)$error$"System command failed:\n"++cmd-- | Execute a system command with a specified current working directory (first argument).-- This function will raise an error if the exit code is non-zero.-- Before running 'systemCwd' make sure you 'need' any required files.---- > systemCwd "/usr/MyDirectory" "pwd" []systemCwd::FilePath->FilePath->[String]->Action()systemCwdcwdpathargs=doletpath2=toNativepathletcmd=unwords$path2:argsputLoudcmdres<-traced("system "++cmd)$do-- FIXME: Should I be using the non-exported System.Process.syncProcess?-- That installs/removes signal handlers.hdl<-runProcesspath2args(Justcwd)NothingNothingNothingNothingwaitForProcesshdlwhen(res/=ExitSuccess)$error$"System command failed:\n"++cmd-- | Execute a system command, returning @(stdout,stderr)@.-- This function will raise an error if the exit code is non-zero.-- Before running 'systemOutput' make sure you 'need' any required files.systemOutput::FilePath->[String]->Action(String,String)systemOutputpathargs=doletpath2=toNativepathletcmd=unwords$path2:argsputLoudcmd(res,stdout,stderr)<-traced("system' "++cmd)$readProcessWithExitCodepath2args""when(res/=ExitSuccess)$error$"System command failed:\n"++cmd++"\n"++stderrreturn(stdout,stderr)-- | @copyFile old new@ copies the existing file from @old@ to @new@. The @old@ file is has 'need' called on it-- before copying the file.copyFile'::FilePath->FilePath->Action()copyFile'oldnew=need[old]>>liftIO(copyFileoldnew)-- | Read a file, after calling 'need'.readFile'::FilePath->ActionStringreadFile'x=need[x]>>liftIO(readFilex)-- | Write a file, lifted to the 'Action' monad.writeFile'::FilePath->String->Action()writeFile'namex=liftIO$writeFilenamex-- | A version of 'readFile'' which also splits the result into lines.readFileLines::FilePath->Action[String]readFileLines=fmaplines.readFile'-- | A version of 'writeFile'' which writes out a list of lines.writeFileLines::FilePath->[String]->Action()writeFileLinesname=writeFile'name.unlines-- | Write a file, but only if the contents would change.writeFileChanged::FilePath->String->Action()writeFileChangednamex=liftIO$dob<-doesFileExistnameifnotbthenwriteFilenamexelsedoorig<-BS.readFilenameletnew=BS.packxwhen(orig/=new)$BS.writeFilenamenew