{-# LANGUAGE OverloadedStrings #-} -- import Data.Char -- import Data.Monoid import System.Directory import System.FilePath.Posix -- import System.IO import Test.CommonUtils import Turtle hiding (FilePath,(<.>)) import qualified Data.Set as Set import qualified Data.Text as T import qualified Data.Text.IO as T -- import qualified GHC.IO.Handle.Text as GHC import Test.HUnit main :: IO () main = do packages <- allCabalPackages -- packages <- allCabalPackagesTest myecho (T.pack $ "number of packages:" ++ (show $ length packages)) packageDirsFull <- drop 2 <$> getDirectoryContents hackageWorkDir let cond c = c == '.' || c == '-' || isDigit c let packageDirs = map (T.dropWhileEnd cond . T.pack) packageDirsFull isBadPackages <- doesFileExist badpackagesFile badPackages <- if isBadPackages then T.lines <$> T.readFile badpackagesFile else return [] let alreadyUnpacked = Set.fromList $ packageDirs ++ badPackages _ <- shell ("mkdir -p " <> (T.pack hackageWorkDir)) empty mapM_ (preparePackage alreadyUnpacked) packages -- --------------------------------------------------------------------- preparePackage :: Set.Set Text -> Text -> IO () preparePackage alreadyUnpacked package = do myecho $ "preparePackage:" <> package if Set.member package alreadyUnpacked then myecho $ "already unpacked:" <> package else preparePackage' package preparePackage' :: Text -> IO () preparePackage' package = do (ec,dir) <- shellStrict ("cabal get --destdir=" <> T.pack hackageWorkDir <> " " <> package) empty -- myecho (T.pack $ "cabal get:" ++ show dir) myecho (T.pack $ show ec) when (ec == ExitSuccess) $ do let bits = T.splitOn " " (head $ T.lines dir) myecho (T.pack $ "cabal get:dir=" ++ show (last bits)) cleanPackage (last bits) return () -- --------------------------------------------------------------------- -- |Clean up whitespace in a package cleanPackage :: Text -> IO () cleanPackage dir = do myecho ("cleaning:" <> dir) fs <- findSrcFiles (T.unpack dir) let doOne :: FilePath -> IO () doOne fn = do myecho ("doOne:" <> T.pack fn) let tmpFn = fn <.> "clean" clean <- cleanupWhiteSpace fn writeFile tmpFn clean removeFile fn renameFile tmpFn fn return () mapM_ doOne fs myecho ("cleaned up:" <> dir) -- --------------------------------------------------------------------- -- | The computation 'writeFile' @file str@ function writes the string @str@, -- to the file @file@. -- writeFileUtf8 :: FilePath -> String -> IO () -- writeFileUtf8 ff txt = withFile ff WriteMode (\ hdl -> hSetEncoding hdl utf8 >> GHC.hPutStr hdl txt) -- --------------------------------------------------------------------- -- allCabalPackagesTest :: IO [Text] -- allCabalPackagesTest -- = return ["3d-graphics-examples","3dmodels","4Blocks","AAI","ABList"] -- -- = return ["airship"] allCabalPackages :: IO [Text] allCabalPackages = do -- let cmd = "cabal list --simple-output | awk '{ print $1 }' | uniq" let cmd = "cabal list --simple-output | awk '{ print $1 }' | sort | uniq" (_ec,r) <- shellStrict cmd empty let packages = T.lines r myecho (T.pack $ show $ take 5 packages) return packages -- --------------------------------------------------------------------- -- |strip trailing whitespace, and turn tabs into spaces cleanupWhiteSpace :: FilePath -> IO String cleanupWhiteSpace file = do contents <- readFileGhc file let cleaned = map cleanupOneLine (lines $ contents) return (unlines cleaned) tabWidth :: Int tabWidth = 8 -- nonBreakingSpace :: Char -- nonBreakingSpace = '\xa0' cleanupOneLine :: String -> String cleanupOneLine str = str' where numSpacesForTab n = tabWidth - (n `mod` tabWidth) -- loop over the line, keeping current pos. Where a tab is found, insert -- spaces until the next tab stop. Discard any trailing whitespace. go col res cur = case cur of [] -> res ('\t':cur') -> go (col + toAdd) ((replicate toAdd ' ') ++ res) cur' where toAdd = numSpacesForTab col ('\xa0':cur') -> go (col + 1) (' ':res) cur' -- convert ISO 8859-16 euro symbol to the UTF8 equivalent -- ('\xa4':cur') -> go (col + 1) ('\x20ac':res) cur' (c:cur') ->go (col + 1) (c:res) cur' str1 = go 0 [] str str' = reverse $ dropWhile isSpace str1 -- --------------------------------------------------------------------- tt :: IO Counts tt = runTestTT $ TestList [ testCleanupOneLine , testTabs ] testCleanupOneLine :: Test testCleanupOneLine = do let makeCase n = (show n ,(replicate n ' ') <> "\t|" <> replicate n ' ' <> "\t" ,(replicate 8 ' ' <> "|")) mkTest n = TestCase $ assertEqual name outp (cleanupOneLine inp) where (name,inp,outp) = makeCase n testList "cleanupOneLine" $ map mkTest [1..7] testTabs :: Test testTabs = TestCase $ assertEqual "testTabs" t2tabsExpected (cleanupOneLine t2tabs) where t2tabs = "import Data.Foldable\t\t ( foldMap )" t2tabsExpected ="import Data.Foldable ( foldMap )" testList :: String -> [Test] -> Test testList str ts = TestLabel str (TestList ts) -- --------------------------------------------------------------------- myecho :: T.Text -> IO () myecho t = mapM_ echo (textToLines t) -- --------------------------------------------------------------------- pwd :: IO FilePath pwd = getCurrentDirectory mcd :: FilePath -> IO () mcd = setCurrentDirectory