-- | Functions for file handling in the master node. module FeedGipeda.Master.File ( writeBenchmarkCSV , isBenchmarkCSV , generateBacklog , writeBacklog , readBacklog , isBacklog , repoOfPath ) where import Data.Char (toLower) import Data.Functor import Data.List (isSuffixOf) import Data.Maybe (listToMaybe) import Data.Set (Set) import qualified Data.Set as Set import FeedGipeda.GitShell (SHA) import qualified FeedGipeda.GitShell as GitShell import FeedGipeda.Repo (Repo) import qualified FeedGipeda.Repo as Repo import System.Directory (createDirectoryIfMissing, doesFileExist, getCurrentDirectory, getDirectoryContents) import System.FilePath (dropFileName, makeRelative, normalise, splitDirectories, takeBaseName, takeBaseName, takeExtension, takeFileName, (<.>), ()) -- Until this is done by gipeda, we have to also produce the backlog on our own. generateBacklog :: Repo -> IO (Set SHA) generateBacklog repo = do projectDir <- Repo.projectDir repo path <- Repo.cloneDir repo hasClone <- GitShell.isRepositoryRoot path if not hasClone -- This should never be true, actually then return Set.empty else do allCommits <- GitShell.allCommits path resultsDir <- Repo.resultsDir repo createDirectoryIfMissing True resultsDir alreadyHandledCommits <- Set.fromList . map takeBaseName <$> getDirectoryContents resultsDir return (Set.difference allCommits alreadyHandledCommits) writeBacklog :: Repo -> Set SHA -> IO () writeBacklog repo backlog = do backlogFile <- Repo.backlogFile repo writeFile backlogFile (unlines (Set.toList backlog)) readBacklog :: Repo -> IO (Set SHA) readBacklog repo = do backlog <- Repo.backlogFile repo exists <- doesFileExist backlog if exists then Set.fromList . lines <$> readFile backlog else return Set.empty matchProjectRelativeDirectory :: [String] -> FilePath -> FilePath -> Bool matchProjectRelativeDirectory subDirs cwd path = let splitNormalisedDirs :: [String] splitNormalisedDirs = splitDirectories (makeRelative cwd (normalise (dropFileName path))) in length splitNormalisedDirs == length subDirs + 1 && subDirs `isSuffixOf` splitNormalisedDirs isBacklog :: FilePath -> FilePath -> Bool isBacklog cwd path = and [ map toLower (takeBaseName path) == "backlog" , map toLower (takeExtension path) == ".txt" , matchProjectRelativeDirectory [] cwd path ] writeBenchmarkCSV :: Repo -> SHA -> String -> IO () writeBenchmarkCSV repo commit result = do cwd <- getCurrentDirectory writeFile (cwd Repo.uniqueName repo "site" "out" "results" commit <.> "csv") result isBenchmarkCSV :: FilePath -> FilePath -> Bool isBenchmarkCSV cwd path = map toLower (takeExtension path) == ".csv" && matchProjectRelativeDirectory ["site", "out", "results"] cwd path repoOfPath :: FilePath -> Set Repo -> FilePath -> IO (Maybe Repo) repoOfPath cwd activeRepos path = let uniqueName :: FilePath -> Maybe String uniqueName = listToMaybe . splitDirectories . makeRelative cwd in case uniqueName path of Nothing -> return Nothing Just name -> do let path = cwd name "repository" hasClone <- GitShell.isRepositoryRoot path if not hasClone then return Nothing else do repo <- GitShell.remoteRepo path if not (Set.member repo activeRepos) then return Nothing else return (Just repo)